React数据获取后props传入数组更新 子组件未触发重新渲染问题
问题原因&解决方案
1. 修正useEffect错误依赖
你第一个监听URL参数的useEffect把整个props对象加入了依赖数组,props每次组件渲染都会生成新的引用,会导致useEffect无意义的频繁触发,甚至引发状态更新混乱,直接修改依赖数组即可:
// 修改前 useEffect(() => { if(parameter1) { setProfileViewing(parameter1); } }, [props, parameter1]); // 修改后 useEffect(() => { if(parameter1) { setProfileViewing(parameter1); } }, [parameter1]);
2. 强制更新状态引用
React状态更新采用浅比较逻辑,如果你调用的getActivityArray方法返回的是原有数组的引用(比如方法内部修改入参数组后直接返回),React会判定状态没有变化,不会触发重渲染。你可以在更新状态时强制生成新的数组引用:
// 修改setProfileActivity调用逻辑 const activity = await getActivityArray(profile.latestActivity); setProfileActivity([...activity]); // 展开生成全新数组
3. 优化loading状态更新逻辑
你单独用第三个useEffect监听两个状态来更新loading,容易出现依赖监听时序问题,直接把loading更新逻辑放到数据拉取的函数中即可,避免多余的状态监听:
async function fetchProfileDetailsAndActivity(username) { try { setLoading(true); // 拉取前先开启加载状态 const profile = await getUserDetailsFromUsername(username); setProfileDetails(profile); const activity = await getActivityArray(profile.latestActivity); setProfileActivity([...activity]); setLoading(false); // 所有数据拉取完成后直接关闭加载 } catch(error) { setLoading(false); // 原有错误处理逻辑 } }
修改完成后可以删除原来用来更新loading的第三个useEffect。
4. 给子组件绑定关联key
如果切换用户时需要子组件强制重新挂载渲染,可以给ProfileActivity组件绑定和当前展示用户关联的key,当key变化时React会销毁旧组件实例,创建全新的组件实例渲染最新数据:
<ProfileActivity key={profileViewing} profileDetails={profileDetails} profileActivity={profileActivity} loading={loading} />
额外排查点
如果上述修改后仍有问题,检查子组件ProfileActivity是否被React.memo包裹,如果使用了memo优化,要么移除memo,要么给memo传入自定义的比较函数,主动判断props是否发生变化。
内容的提问来源于stack exchange,提问作者9bp7
相关产品推荐
相关产品推荐

