v6路由守卫与权限控制结合

DeadBear +0/-0 0 0 正常 2025-12-24T07:01:19 React-Router · 权限控制

React Router v6的路由守卫与权限控制结合是升级过程中的核心议题。在v6中,useRoutesuseNavigate等API的变更使得传统的路由守卫实现方式需要重构。

核心实现方案

1. 自定义Hook封装

const useAuth = () => {
  const [isAuthenticated, setIsAuthenticated] = useState(false);
  const [loading, setLoading] = useState(true);
  
  useEffect(() => {
    // 检查认证状态
    const checkAuth = async () => {
      const token = localStorage.getItem('token');
      if (token) {
        try {
          const response = await fetch('/api/auth/check', {
            headers: { Authorization: `Bearer ${token}` }
          });
          setIsAuthenticated(response.ok);
        } catch {
          setIsAuthenticated(false);
        }
      }
      setLoading(false);
    };
    checkAuth();
  }, []);
  
  return { isAuthenticated, loading };
};

2. 路由守卫组件

const ProtectedRoute = ({ children }) => {
  const { isAuthenticated, loading } = useAuth();
  const navigate = useNavigate();
  
  useEffect(() => {
    if (!loading && !isAuthenticated) {
      navigate('/login', { replace: true });
    }
  }, [isAuthenticated, loading, navigate]);
  
  if (loading) return <div>Loading...</div>;
  return isAuthenticated ? children : null;
};

3. 路由配置整合

const App = () => {
  const routes = useRoutes([
    { path: '/', element: <Home /> },
    { 
      path: '/dashboard', 
      element: (
        <ProtectedRoute>
          <Dashboard />
        </ProtectedRoute>
      ) 
    },
    { path: '/login', element: <Login /> }
  ]);
  
  return routes;
};

迁移注意事项

  • v6移除了Switch组件,需使用useRoutes替代
  • 权限控制逻辑需要与路由配置解耦,提高可维护性
  • 建议统一管理认证状态,避免重复请求

此方案在实际项目中已验证可用,建议按需调整权限检查逻辑。

推广
广告位招租

讨论

0/2000
FastMoon
FastMoon · 2026-01-08T10:24:58
v6的useRoutes重构确实让路由守卫实现更灵活,但要注意别把auth逻辑耦合到路由层级,建议用context或store统一管理认证状态,避免每个组件都重复fetch token。
SickIron
SickIron · 2026-01-08T10:24:58
ProtectedRoute写法不错,但loading状态下直接return null可能让用户卡住,建议加个spinner或者redirect到login页,用户体验会好很多,特别是移动端