React Router 指向同组件传不同props时组件不重新渲染问题
问题原因
- 两个
<Link>指向同一路由路径/FAQ,React Router默认会复用已挂载的Faq组件实例,仅更新组件props,不会触发组件的卸载重挂载流程。 - Accordion组件的
preExpanded属于初始化属性,仅在组件首次挂载时生效,后续props变更时不会自动更新展开状态,因此你即使拿到了新的location.state值,Accordion也不会响应变化。
解决方案
方案1:强制Faq组件重新挂载(改造成本最低)
修改App.js中的路由定义,给Faq组件绑定随location.state变化的唯一key,触发组件卸载重挂载,让preExpanded每次都能生效:
// App.js 调整Route写法 function App() { return ( <Router> <div className="App"> <Switch> <Route path="/" exact component={Main}/> {/* 改用render方法传递key,key变化时组件会重新挂载 */} <Route path="/FAQ" render={({location}) => <Faq key={location.state?.Display || location.key} location={location} />} /> </Switch> </div> </Router> ); }
方案2:将Accordion改为受控模式(性能最优)
不需要重挂载整个Faq组件,通过useEffect监听location.state变化,手动控制Accordion的展开状态:
// Faq.js 调整为受控写法 import { useState, useEffect } from 'react'; function Faq(props) { // 用state管理Accordion的激活项 const [activeKey, setActiveKey] = useState(props.location.state.Display); // 监听state变化,更新激活项 useEffect(() => { setActiveKey(props.location.state.Display); }, [props.location.state.Display]); return ( {/* 把preExpanded替换为受控属性activeKey,不同Accordion库的属性名可能有差异,以你用的库文档为准 */} <Accordion className="accordion" activeKey={activeKey} onSelect={setActiveKey} > {/* 其余Accordion子项代码 */} </Accordion> ) }
内容的提问来源于stack exchange,提问作者markinjo
相关产品推荐
相关产品推荐

