React JS报错:渲染其他组件时无法更新组件 代码问题咨询
问题根因
你贴的这段代码本身不存在渲染时同步调用setState的问题,因为状态更新是放在useEffect(组件渲染完成后触发)的回调里执行的,但是触发警告有两个常见的关联问题:
- 你给同步的
localStorage.getItem加了不必要的async/await,虽然不会直接触发警告,但会导致状态更新延迟到下一个微任务节点,如果此时你的父/子组件刚好处于渲染流程,就容易触发跨组件更新的警告 - 更核心的原因是:
isAuth状态更新后,你大概率在MyApp的渲染逻辑里直接触发了redux的状态派发(比如直接写了props.setAuth(isAuth)这种同步调用),而Connect(HeaderComponent)是订阅了该redux状态的组件,此时MyApp还没完成渲染流程,就触发了Header的更新,就会报这个警告。
写法修正方案
- 首先去掉不必要的async/await:
localStorage.getItem是同步API,不需要异步等待
const [isAuth, setIsAuth] = useState(false); const [firstRender, setFirstRender] = useState(false); useEffect(() => { getSignInInfo(); },[]); const getSignInInfo = () => { const authRes = localStorage.getItem("OAUTH_RES"); setFirstRender(true); setIsAuth(authRes); };
- 如果需要把登录态同步到redux,不要在MyApp的render返回逻辑里同步派发,要放在useEffect的回调里执行:
// 错误写法 不要在渲染逻辑里直接调用dispatch // if (isAuth) props.dispatch(changeAuth(isAuth)) // return <div>...</div> // 正确写法 单独用useEffect监听isAuth变化后派发 useEffect(() => { if (firstRender) { props.dispatch(changeAuth(isAuth)) } }, [isAuth, firstRender, props.dispatch])
必须注意的事项
- React组件渲染过程中不能同步触发其他组件的状态更新,所有跨组件的状态修改、redux派发操作,要么放在事件回调里,要么放在useEffect等渲染结束后触发的回调里
- 不要给同步API加async/await,不必要的异步包装会打乱状态更新的时序,增加不可控的渲染冲突风险
- 如果你用了react-redux的connect,所有状态更新尽量走redux的数据流,不要混用组件内部state和全局状态来维护同一个业务字段,避免多来源更新导致的时序冲突。
内容的提问来源于stack exchange,提问作者Aniket Yadav
相关产品推荐
相关产品推荐

