如何在MobX可观察值isSyncInProcess变化时重载React函数式组件
问题解决方法
根本原因说明
- 你写的空回调
useEffect没有任何触发逻辑,自然无法产生效果 - 子组件内部的API/查询如果是仅在挂载阶段触发(比如依赖为空数组的
useEffect),默认情况下父组件重渲染时,只要子组件的props、key没有变化,React会复用现有子组件实例,不会重新挂载,自然不会重新触发内部请求 - 哪怕
isSyncInProcess变化会触发useObserver包裹的父组件重渲染,也不会直接带动子组件的内部请求重跑
方案1:给子组件绑定关联isSyncInProcess的key(最便捷,无需修改子组件代码)
React遇到key变化的组件时,会直接卸载旧组件实例,重新挂载新的实例,子组件的挂载阶段逻辑会完整重新执行,自动触发内部API请求。
修改后的代码示例:
export const Main = ({ permissions }) => { return useObserver(() => { const { datastore : { isSyncInProcess } } = stores; const renderSwitch = section => { // 给所有返回的子组件加上key,绑定isSyncInProcess switch (section) { case Parent.A: if (value) { return <B key={isSyncInProcess} /> } return <C key={isSyncInProcess} /> case Parent.D: return <E key={isSyncInProcess} /> default: return <F key={isSyncInProcess} permissions={permissions} /> } }; return ( <React.Fragment> {/* 修正原代码的语法错误,把:改为&&判断section存在 */} { section ? renderSwitch(section) : null } </React.Fragment> ); }); };
如果嫌每个子组件加key麻烦,也可以在返回时套一层容器统一加key:
return ( <React.Fragment> { section ? <div key={isSyncInProcess}>{renderSwitch(section)}</div> : null } </React.Fragment> );
方案2:将isSyncInProcess作为props传给子组件,修改子组件的请求依赖(性能更优)
如果不想触发子组件的卸载/挂载流程,可以把isSyncInProcess作为props传递给所有子组件,然后修改子组件内部请求的useEffect依赖数组,把这个props加入依赖,值变化时就会自动重跑请求逻辑。
子组件示例修改:
// 子组件F的示例代码 const F = ({ permissions, isSyncInProcess }) => { React.useEffect(() => { // 原本的API请求逻辑 fetchData(); }, [permissions, isSyncInProcess]); // 加入isSyncInProcess作为依赖 return <div>...</div> };
额外检查项
确保isSyncInProcess已经被MobX正确标记为observable,否则useObserver无法监听到它的变化,父组件本身就不会重渲染。
内容的提问来源于stack exchange,提问作者ganesh kaspate
相关产品推荐
相关产品推荐

