## 主要改动 ### 新增 - 创建 `store/slices/authModalSlice.js` - Redux Slice 管理认证弹窗状态 - 创建 `hooks/useAuthModal.js` - 自定义 Hook,组合 Redux 状态和业务逻辑 ### 修改 - 更新 `store/index.js` - 添加 authModal reducer - 更新 `App.js` - 移除 AuthModalProvider 包裹层 - 更新 5 个组件的 import 路径: - AuthFormContent.js - AuthModalManager.js - WechatRegister.js - HomeNavbar.js - ProtectedRoute.js ### 删除 - 删除 `contexts/AuthModalContext.js` - 旧的 Context 实现 ## 迁移效果 - ✅ 减少 Provider 嵌套层级(4层 → 3层) - ✅ 统一状态管理架构(Redux) - ✅ 更好的调试体验(Redux DevTools) - ✅ 保持 API 兼容性(无破坏性修改) ## 技术细节 - 使用 `useRef` 存储 `onSuccessCallback`(函数不可序列化) - 保持与 AuthContext 的依赖关系(AuthProvider 暂未迁移) - 所有业务逻辑保持不变,仅改变状态管理方式 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
106 lines
2.7 KiB
JavaScript
106 lines
2.7 KiB
JavaScript
// src/components/Auth/AuthModalManager.js
|
||
import React from 'react';
|
||
import {
|
||
Modal,
|
||
ModalOverlay,
|
||
ModalContent,
|
||
ModalBody,
|
||
ModalCloseButton,
|
||
useBreakpointValue
|
||
} from '@chakra-ui/react';
|
||
import { useAuthModal } from '../../hooks/useAuthModal';
|
||
import AuthFormContent from './AuthFormContent';
|
||
|
||
/**
|
||
* 全局认证弹窗管理器
|
||
* 统一的登录/注册弹窗
|
||
*/
|
||
export default function AuthModalManager() {
|
||
const {
|
||
isAuthModalOpen,
|
||
closeModal
|
||
} = useAuthModal();
|
||
|
||
// 响应式尺寸配置
|
||
const modalSize = useBreakpointValue({
|
||
base: "md", // 移动端:md(不占满全屏)
|
||
sm: "md", // 小屏:md
|
||
md: "lg", // 中屏:lg
|
||
lg: "xl" // 大屏:xl(更紧凑)
|
||
});
|
||
|
||
// 响应式宽度配置
|
||
const modalMaxW = useBreakpointValue({
|
||
base: "90%", // 移动端:屏幕宽度的90%
|
||
sm: "90%", // 小屏:90%
|
||
md: "700px", // 中屏:固定700px
|
||
lg: "700px" // 大屏:固定700px
|
||
});
|
||
|
||
// 响应式水平边距
|
||
const modalMx = useBreakpointValue({
|
||
base: 4, // 移动端:左右各16px边距
|
||
md: "auto" // 桌面端:自动居中
|
||
});
|
||
|
||
// 响应式垂直边距
|
||
const modalMy = useBreakpointValue({
|
||
base: 8, // 移动端:上下各32px边距
|
||
md: 8 // 桌面端:上下各32px边距
|
||
});
|
||
|
||
// 条件渲染:只在打开时才渲染 Modal,避免创建不必要的 Portal
|
||
if (!isAuthModalOpen) {
|
||
return null;
|
||
}
|
||
|
||
return (
|
||
<Modal
|
||
isOpen={isAuthModalOpen}
|
||
onClose={closeModal}
|
||
size={modalSize}
|
||
isCentered
|
||
closeOnOverlayClick={false} // 防止误点击背景关闭
|
||
closeOnEsc={true} // 允许ESC键关闭
|
||
scrollBehavior="inside" // 内容滚动
|
||
zIndex={999} // 低于导航栏(1000),不覆盖导航
|
||
>
|
||
{/* 半透明背景 + 模糊效果 */}
|
||
<ModalOverlay
|
||
bg="blackAlpha.700"
|
||
backdropFilter="blur(10px)"
|
||
/>
|
||
|
||
{/* 弹窗内容容器 */}
|
||
<ModalContent
|
||
bg="white"
|
||
boxShadow="2xl"
|
||
borderRadius="2xl"
|
||
maxW={modalMaxW}
|
||
mx={modalMx}
|
||
my={modalMy}
|
||
position="relative"
|
||
>
|
||
{/* 关闭按钮 */}
|
||
<ModalCloseButton
|
||
position="absolute"
|
||
right={4}
|
||
top={4}
|
||
zIndex={9999}
|
||
color="gray.500"
|
||
bg="transparent"
|
||
_hover={{ bg: "gray.100" }}
|
||
borderRadius="full"
|
||
size="lg"
|
||
onClick={closeModal}
|
||
/>
|
||
|
||
{/* 弹窗主体内容 */}
|
||
<ModalBody p={6}>
|
||
<AuthFormContent />
|
||
</ModalBody>
|
||
</ModalContent>
|
||
</Modal>
|
||
);
|
||
}
|