v6路由权限控制踩坑:自定义Hook实现路由守卫经验

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

v6路由权限控制踩坑:自定义Hook实现路由守卫经验

React Router v6相比v5在路由权限控制方面有了较大变化,特别是在<Route>组件的使用方式上。本文将分享在实际项目中通过自定义Hook实现路由守卫的经验。

问题背景

在v6中,<Route>不再支持直接使用component属性,而是需要使用element属性来传递组件。这导致原有的权限控制逻辑需要重新设计。

解决方案

我们创建了一个自定义Hook useAuth 来处理权限验证:

import { useEffect, useState } from 'react';
import { useNavigate } from 'react-router-dom';

export const useAuth = () => {
  const [isAuthenticated, setIsAuthenticated] = useState(false);
  const [loading, setLoading] = useState(true);
  const navigate = useNavigate();

  useEffect(() => {
    const checkAuth = async () => {
      try {
        // 模拟权限检查
        const token = localStorage.getItem('token');
        if (token) {
          setIsAuthenticated(true);
        } else {
          navigate('/login');
        }
      } catch (error) {
        navigate('/login');
      } finally {
        setLoading(false);
      }
    };

    checkAuth();
  }, [navigate]);

  return { isAuthenticated, loading };
};

然后创建一个ProtectedRoute组件:

import { Navigate } from 'react-router-dom';
import { useAuth } from './useAuth';

export const ProtectedRoute = ({ children }) => {
  const { isAuthenticated, loading } = useAuth();

  if (loading) return <div>Loading...</div>;
  
  return isAuthenticated ? children : <Navigate to="/login" />;
};

使用方式

在路由配置中使用:

import { BrowserRouter, Routes, Route } from 'react-router-dom';

function App() {
  return (
    <BrowserRouter>
      <Routes>
        <Route path="/login" element={<Login />} />
        <Route 
          path="/dashboard" 
          element={
            <ProtectedRoute>
              <Dashboard />
            </ProtectedRoute>
          }
        />
      </Routes>
    </BrowserRouter>
  );
}

踩坑经验

  1. 注意useNavigate的使用时机,避免在组件卸载后调用
  2. 权限检查逻辑要处理异步情况
  3. 路由守卫需要考虑加载状态的显示

通过这种方式,我们成功实现了v6版本的路由权限控制。

推广
广告位招租

讨论

0/2000
FreeIron
FreeIron · 2026-01-08T10:24:58
v6的element替代component确实让权限控制更灵活,但需要重新思考组件结构设计
BadLeaf
BadLeaf · 2026-01-08T10:24:58
useAuth hook的loading状态处理很关键,避免白屏或重复跳转问题
ThinGold
ThinGold · 2026-01-08T10:24:58
建议在auth hook中加入token过期检测,而不仅仅是存在性判断
LowLeg
LowLeg · 2026-01-08T10:24:58
ProtectedRoute组件应该支持动态路由参数传递,避免children丢失props
FalseSkin
FalseSkin · 2026-01-08T10:24:58
可以考虑将权限检查逻辑抽离到单独的service层,便于单元测试
Adam176
Adam176 · 2026-01-08T10:24:58
别忘了处理403权限拒绝场景,不只做登录跳转而是提示用户无权访问
TallDonna
TallDonna · 2026-01-08T10:24:58
建议在useAuth中加入错误重试机制,网络波动时避免频繁跳转
LongQuincy
LongQuincy · 2026-01-08T10:24:58
路由守卫应该支持多角色权限判断,而不仅是简单登录状态验证
Eve35
Eve35 · 2026-01-08T10:24:58
可以结合context或redux管理全局auth状态,避免每个组件都重复检查
Adam965
Adam965 · 2026-01-08T10:24:58
使用useEffect监听路由变化时要注意清理副作用,防止内存泄漏