Files
vf_react/src/components/ProtectedRoute.js
2025-10-24 12:19:37 +08:00

52 lines
1.8 KiB
JavaScript
Executable File
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/components/ProtectedRoute.js - 弹窗拦截版本
import React, { useEffect, useRef } from 'react';
import { Box, VStack, Spinner, Text } from '@chakra-ui/react';
import { useAuth } from '../contexts/AuthContext';
import { useAuthModal } from '../contexts/AuthModalContext';
const ProtectedRoute = ({ children }) => {
const { isAuthenticated, isLoading, user } = useAuth();
const { openAuthModal, isAuthModalOpen } = useAuthModal();
// ⚡ 使用 useRef 保存当前路径,避免每次渲染创建新字符串导致 useEffect 无限循环
const currentPathRef = useRef(window.location.pathname + window.location.search);
// 未登录时自动弹出认证窗口
useEffect(() => {
if (!isLoading && !isAuthenticated && !user && !isAuthModalOpen) {
openAuthModal(currentPathRef.current);
}
// ⚠️ 移除 user 依赖,因为 user 对象每次从 API 返回都是新引用,会导致无限循环
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [isAuthenticated, isLoading, isAuthModalOpen, openAuthModal]);
// 显示加载状态
if (isLoading) {
return (
<Box
height="100vh"
display="flex"
alignItems="center"
justifyContent="center"
bg="gray.50"
>
<VStack spacing={4}>
<Spinner size="xl" color="blue.500" thickness="4px" />
<Text fontSize="lg" color="gray.600">正在验证登录状态...</Text>
</VStack>
</Box>
);
}
// 未登录时,渲染子组件 + 自动打开弹窗(通过 useEffect
// 弹窗会在 useEffect 中自动触发,页面正常显示
if (!isAuthenticated || !user) {
return children;
}
// 已登录,渲染子组件
return children;
};
export default ProtectedRoute;