React Router 6应用首次加载仅单次重定向的实现问题
问题原因
当前代码重定向失效的核心问题有两个:
useEffect执行时机在组件完成渲染之后,你在effect中修改局部变量el时,组件已经把初始的<h1>hellooooo</h1>返回并渲染了,局部变量修改不会触发视图更新。即使你调用setFirstRender触发二次渲染,下一轮渲染开头又会重新给el赋值为h1元素,<Navigate>组件从来没有被真正返回渲染,自然无法触发跳转。- 单独封装
Test组件、用组件内状态控制首次渲染的逻辑完全冗余,React Router v6原生支持路由级重定向,不需要额外写状态判断。
实现方案
方案1:默认路由直接重定向(最常用,匹配到/就跳)
如果你的需求是所有访问根路径/的场景都跳转到/companies,直接删除多余的Test组件,在路由表中直接配置重定向即可,不需要额外状态:
import React from 'react'; import { Routes, Route, BrowserRouter as Router, Navigate } from 'react-router-dom'; import { port } from './variables/global'; import "./assets/css/mdb.css"; import Companies from './components/Companies'; import Company from './components/Company'; import NavbarDev from './components/NavbarDev'; import WebFont from 'webfontloader'; WebFont.load({ google: { families: ['Barlow', 'Playfair Display', 'Overpass'] } }); function CompaniesRouter() { return ( <Routes> <Route path="/" element={<Companies />} /> <Route path="/last" element={<Company />} /> </Routes> ) } export default ({ history }) => { const whatPort = location.port; return ( <Router history={history}> {(process.env.NODE_ENV === 'development' && whatPort === port.toString()) ? <NavbarDev /> : ''} <Routes> <Route path="/companies/*" element={<CompaniesRouter />} /> <Route path="/user/settings" element={<Companies />} /> <Route path='/' element={<Navigate replace to="/companies" />} /> <Route path="*" element={<Navigate to="/" replace />} /> </Routes> </Router> ); };
方案2:仅应用首次加载时跳转(后续回退到/不触发跳转)
如果你要的是仅整个应用第一次打开时跳一次,之后用户手动导航回根路径/时保留首页内容不跳转,不需要用useState+useEffect做判断,用模块级变量标记首次加载状态即可,避免渲染时机问题:
// 模块初始化时定义标记,整个应用生命周期仅重置一次 let hasAppLoaded = false; function RootPage() { if (!hasAppLoaded) { hasAppLoaded = true; return <Navigate replace to="/companies" />; } // 非首次加载访问/时,渲染根页面内容 return ( <> <h1>hellooooo</h1> </> ) } // 路由表中替换原来的Test组件即可 <Route path='/' element={<RootPage />} />
这种写法在组件渲染阶段直接判断返回对应元素,没有effect执行时机的延迟问题,也不会产生多余的重复渲染,逻辑更简洁可靠。
内容的提问来源于stack exchange,提问作者melv3223
相关产品推荐
相关产品推荐

