Files
vf_react/src/hooks/useAuthModal.js

98 lines
3.1 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// src/hooks/useAuthModal.js
// 认证弹窗自定义 Hook - 组合 Redux 状态和业务逻辑
import { useCallback, useRef } from 'react';
import { useDispatch, useSelector } from 'react-redux';
import { useNavigate } from 'react-router-dom';
import {
openModal,
closeModal,
selectAuthModalOpen,
selectRedirectUrl
} from '../store/slices/authModalSlice';
import { useAuth } from '../contexts/AuthContext';
/**
* 认证弹窗自定义 Hook
*
* 功能:
* - 管理认证弹窗的开关状态
* - 处理登录成功后的回调和跳转
* - 未登录时关闭弹窗自动跳转到首页
*
* 注意:
* - onSuccessCallback 使用 ref 存储(函数不可序列化,不能放 Redux
* - 依赖 AuthContext 读取 isAuthenticatedAuthProvider 暂未迁移)
*
* @returns {object} 弹窗状态和操作方法
*/
export const useAuthModal = () => {
const dispatch = useDispatch();
const navigate = useNavigate();
// Redux 状态
const isAuthModalOpen = useSelector(selectAuthModalOpen);
const redirectUrl = useSelector(selectRedirectUrl);
// AuthContext 状态(暂未迁移到 Redux
const { isAuthenticated } = useAuth();
// 使用 ref 存储回调函数(不能放 Redux因为函数不可序列化
const onSuccessCallbackRef = useRef(null);
/**
* 打开认证弹窗(统一的登录/注册入口)
* @param {string} url - 认证成功后的重定向URL可选
* @param {function} callback - 认证成功后的回调函数(可选)
*/
const openAuthModal = useCallback((url = null, callback = null) => {
onSuccessCallbackRef.current = callback;
dispatch(openModal({ redirectUrl: url }));
}, [dispatch]);
/**
* 关闭认证弹窗
* 如果用户未登录且不在首页,跳转到首页
*/
const closeAuthModal = useCallback(() => {
dispatch(closeModal());
onSuccessCallbackRef.current = null;
// ⭐ 如果用户关闭弹窗时仍未登录,且当前不在首页,才跳转到首页
if (!isAuthenticated && window.location.pathname !== '/home') {
navigate('/home');
}
}, [dispatch, isAuthenticated, navigate]);
/**
* 登录/注册成功处理
* @param {object} user - 用户信息
*/
const handleLoginSuccess = useCallback((user) => {
// 执行自定义回调(如果有)
if (onSuccessCallbackRef.current) {
try {
onSuccessCallbackRef.current(user);
} catch (error) {
console.error('useAuthModal: handleLoginSuccess 回调执行失败', error);
}
}
// ⭐ 登录成功后,只关闭弹窗,留在当前页面(不跳转)
// 移除了原有的 redirectUrl 跳转逻辑
dispatch(closeModal());
onSuccessCallbackRef.current = null;
}, [dispatch]);
return {
// 状态
isAuthModalOpen,
redirectUrl,
// 方法
openAuthModal,
closeModal: closeAuthModal,
handleLoginSuccess,
};
};