React中使用可复用navbar时如何实现每页导航栏标题切换
问题根因
你将setTitleApp状态更新逻辑直接写在了组件顶层,每次组件渲染都会触发状态更新,而状态更新又会反过来触发组件重新渲染,形成无限循环,因此触发了React的重渲染次数限制报错。
修复方案
方案1:使用副作用监听路径变化(推荐)
- 先将
<Router>组件移动到index.js中包裹<App />,让App组件处于路由上下文环境中,可以使用路由相关钩子 - 使用
useLocation钩子获取响应式的当前路径,用useEffect包裹标题更新逻辑,仅当路径发生变化时才更新标题,避免无限循环
修正后的App.js代码:
import { useState, useEffect } from 'react'; import { Switch, Route, useLocation } from 'react-router-dom'; // 补充你自己的组件导入路径 import NavBar from './NavBar'; import Springboard from './Springboard'; import Worklist from './Worklist'; import AnalyticsDashboard from './AnalyticsDashboard'; function App() { const [titleApp, setTitleApp] = useState("Home"); const location = useLocation(); useEffect(() => { switch (location.pathname) { case "/": setTitleApp("Home"); break; case "/worklist": setTitleApp("Worklist"); break; case "/analytics": setTitleApp("analytics"); break; default: setTitleApp("Home"); break; } }, [location.pathname]); return ( <div className="GlobalDiv"> <NavBar title={titleApp} /> <div className="MainDiv"> <Switch> <Route exact path="/" component={Springboard} /> <Route exact path="/worklist" component={Worklist} /> <Route path="/analytics" component={AnalyticsDashboard} /> </Switch> </div> </div> ); } export default App;
方案2:直接计算标题(更简洁)
标题逻辑不涉及复杂操作的话,可以完全去掉状态声明,直接根据当前路径计算得到标题,无需额外的状态和副作用:
import { Switch, Route, useLocation } from 'react-router-dom'; // 补充组件导入 import NavBar from './NavBar'; import Springboard from './Springboard'; import Worklist from './Worklist'; import AnalyticsDashboard from './AnalyticsDashboard'; function App() { const location = useLocation(); // 直接计算标题 const getTitle = () => { switch (location.pathname) { case "/": return "Home"; case "/worklist": return "Worklist"; case "/analytics": return "analytics"; default: return "Home"; } } const titleApp = getTitle(); return ( <div className="GlobalDiv"> <NavBar title={titleApp} /> <div className="MainDiv"> <Switch> <Route exact path="/" component={Springboard} /> <Route exact path="/worklist" component={Worklist} /> <Route path="/analytics" component={AnalyticsDashboard} /> </Switch> </div> </div> ); } export default App;
内容的提问来源于stack exchange,提问作者Ingeborg
相关产品推荐
相关产品推荐

