如何将React旧代码升级至React18.2.0+Router DOM v6+MUI5?
React Router v6 升级转换方案
以下是适配最新React版本和react-router-dom v6的完整代码,同时保留JSON路由配置和AuthGuard权限守卫功能:
升级后的App组件代码
import React, { Suspense, Fragment } from "react"; // 替换v5的路由组件为v6版本 import { BrowserRouter, Routes, Route, Outlet } from "react-router-dom"; import { MuiPickersUtilsProvider } from "@material-ui/pickers"; import MomentUtils from "@date-io/moment"; import { routes } from "src/routes"; import AuthGuard from "src/component/AuthGuard"; import { ThemeProvider } from "@material-ui/core"; import { createTheme } from "src/theme"; import { UserContext } from "./context/User"; import PageLoading from "src/component/PageLoading"; // 确保PageLoading组件路径正确 function App() { const theme = createTheme(); return ( <div className="App"> <ThemeProvider theme={theme}> <MuiPickersUtilsProvider utils={MomentUtils}> {/* 修复原代码中上下文组件名称错误 */} <UserContext.Provider> {/* v6用BrowserRouter替代Router+createBrowserHistory,内置历史记录管理 */} <BrowserRouter> <RenderRoutes routes={routes} /> </BrowserRouter> </UserContext.Provider> </MuiPickersUtilsProvider> </ThemeProvider> </div> ); } export default App; // 适配v6的递归路由渲染组件 function RenderRoutes({ routes }) { return ( <Suspense fallback={<PageLoading />}> <Routes> {routes.map((route, index) => { const Component = route.component; const Guard = route.guard ? AuthGuard : Fragment; const Layout = route.layout || Fragment; // 嵌套路由需要通过Outlet渲染子内容 const LayoutWrapper = () => ( <Layout> {route.routes ? <Outlet /> : <Component />} </Layout> ); return ( <Route key={index} path={route.path} element={ <Guard> {/* 区分是否有子路由,决定渲染布局+Outlet还是直接组件 */} {route.routes ? <LayoutWrapper /> : <Layout><Component /></Layout>} </Guard> } > {/* 递归渲染子路由 */} {route.routes && <RenderRoutes routes={route.routes} />} </Route> ); })} </Routes> </Suspense> ); }
AuthGuard权限守卫组件示例
// src/component/AuthGuard.js import { Navigate, useLocation } from "react-router-dom"; import { useContext } from "react"; import { UserContext } from "../context/User"; function AuthGuard({ children }) { // 从上下文获取用户认证状态,需根据实际业务调整 const { isAuthenticated } = useContext(UserContext); const location = useLocation(); // 未认证时跳转到登录页,记录当前路由以便登录后返回 if (!isAuthenticated) { return <Navigate to="/login" state={{ from: location }} replace />; } return children; } export default AuthGuard;
核心升级说明
- 移除createBrowserHistory:v6的
BrowserRouter内置了浏览器历史记录管理,无需单独引入history库 - 路由组件替换:
Switch→Routes,Route的render属性→element属性,默认开启精确匹配无需exact - 嵌套路由处理:通过
Outlet组件渲染子路由内容,父路由内部嵌套子路由实现层级结构 - 权限守卫适配:守卫组件通过包裹
children实现,使用Navigate组件处理未认证跳转逻辑
内容的提问来源于stack exchange,提问作者Bhupender
相关产品推荐
相关产品推荐

