React Router v6报错:IsUserRedirect非Route/React.Fragment组件
解决react-router-dom v6路由配置错误
问题根源
react-router-dom v6完全重构了路由系统,不再支持v5中把自定义路由组件嵌套在<Route>内部的写法。你遇到的错误是因为<Routes>的直接子元素必须是<Route>,且<Route>的内容需通过element属性传递,不能将自定义组件作为<Route>的子节点放置。
解决方案
1. 重构自定义路由组件
修改./helpers/routes.js中的IsUserRedirect和ProtectedRoute,适配v6的API:
// ./helpers/routes.js import { Navigate } from 'react-router-dom'; // 已登录用户重定向组件 export function IsUserRedirect({ user, loggedInPath, children }) { // 如果用户已登录,跳转到指定页面 if (user) { return <Navigate to={loggedInPath} replace />; } // 未登录则渲染传入的子组件 return children; } // 受保护路由组件 export function ProtectedRoute({ user, children }) { // 如果用户未登录,跳转到登录页 if (!user) { return <Navigate to="/signin" replace />; } // 已登录则渲染传入的子组件 return children; }
2. 调整App.js的路由配置
将自定义路由组件作为<Route>的element属性值传入,移除无效的空<Route>标签:
import React from 'react'; import * as ROUTES from './constants/routes'; import { BrowserRouter as Router, Routes, Route } from 'react-router-dom'; import { Browse, Home, Signin, Signup } from './pages'; import { IsUserRedirect, ProtectedRoute } from './helpers/routes'; import { useAuthListener } from './hooks'; function App() { const { user } = useAuthListener(); return ( <Router> <Routes> {/* 登录页:已登录跳转至Browse */} <Route path={ROUTES.SIGN_IN} element={ <IsUserRedirect user={user} loggedInPath={ROUTES.BROWSE}> <Signin /> </IsUserRedirect> } /> {/* 注册页:已登录跳转至Browse */} <Route path={ROUTES.SIGN_UP} element={ <IsUserRedirect user={user} loggedInPath={ROUTES.BROWSE}> <Signup /> </IsUserRedirect> } /> {/* 浏览页:未登录跳转至登录页 */} <Route path={ROUTES.BROWSE} element={ <ProtectedRoute user={user}> <Browse /> </ProtectedRoute> } /> {/* 首页:已登录跳转至Browse */} <Route path={ROUTES.HOME} element={ <IsUserRedirect user={user} loggedInPath={ROUTES.BROWSE}> <Home /> </IsUserRedirect> } /> </Routes> </Router> ); } export default App;
关键说明
<Routes>的直接子元素只能是<Route>组件,不能放置其他自定义组件。<Route>的内容必须通过element属性传递,这是v6的核心规则之一。- 自定义路由组件通过
Navigate组件实现页面跳转,替代v5中的Redirect组件。
内容的提问来源于stack exchange,提问作者iRobot
相关产品推荐
相关产品推荐

