React Router内更新状态变量触发过多重渲染,如何优雅设置Header页标题?
错误原因
你遇到的重渲染错误是因为直接在JSX渲染逻辑中调用了setPageTitle:React每次渲染组件都会执行这段代码更新state,state更新又会触发组件重新渲染,形成无限循环,最终触发重渲染次数限制报错。
推荐实现方案
最简洁易维护的方案是通过监听路由变化统一设置页面标题,不需要把HeaderBar重复放到每个Route内部,代码实现如下:
import { useState, useEffect } from 'react'; import { BrowserRouter as Router, Switch, Route, useLocation } from 'react-router-dom'; // 统一维护路由与页面标题的映射关系 const routeTitleMap = { '/login': 'Login', '/main': 'Main', '/about': 'About' } // 将路由内部逻辑抽离为独立组件,才能正常使用useLocation钩子 function AppContent() { const [pageTitle, setPageTitle] = useState(""); const location = useLocation(); // 仅当路由路径变化时更新页面标题 useEffect(() => { setPageTitle(routeTitleMap[location.pathname] || ""); }, [location.pathname]); return ( <div> <HeaderBar siteTitle="My Website Name" pageTitle={pageTitle} /> <Switch> <Route path="/login"> <h1>Login Page</h1> </Route> <Route path="/main"> <h1>Main Page</h1> </Route> <Route path="/about"> <h1>About Page</h1> </Route> </Switch> </div> ) } function App() { return ( <Router> <AppContent /> </Router> ); }
方案优势
- 所有页面标题统一在
routeTitleMap中管理,后续新增路由只需要添加一条映射关系即可,维护成本极低 - 标题更新逻辑放在
useEffect中,仅在路由路径变化时触发,不会产生多余重渲染 - HeaderBar始终只声明一次,符合优雅性要求
内容的提问来源于stack exchange,提问作者Jyclop
相关产品推荐
相关产品推荐

