报错信息:
Warning: Cannot update a component (`ConnectFunction`) while rendering a different component...
业务场景:
react hooks 写法,组件A嵌套组件B,在A组件中,获取完用户信息,从用户信息中提取某个数据,再填充到model state中,这个在使用dispatch来set state model时,发生了报错。下面是简单的代码示例:
const Layout: FC<PageProps> = ({loading, currentUser}) => {
useEffect(() => {
dispatch({
type: 'user/fetchCurrent'
});
}, []);
if ( currentUser && dispatch ) {
//这里是出现问题的地方
dispatch({
type: 'user/setPermission',
payload: currentUser.permission.find(item.id == pid),
});
}
return <PageHeaderWrapper>{children}</PageHeaderWrapper>;
};
解决办法
从官网上查到了这样的报错信息:
It is supported to call setState during render, but only for the same component. If you call setState during a render on a different component, you will now see a warning:
Warning: Cannot update a component from inside the function body of a different component.
官网页面地址:pl.reactjs.org/blog/2020/0…
从上面的描述中了解到,支持在同一个组件渲染过程中去set state,但如果在不同的组件渲染过程中去set state时,就会报这个warning。
从业务的场景来说,在dispatch时,并无阻塞加载,此时chidren组件渲染,在渲染过程中,父组件又更新了state,这时父组件又要重新渲染,这与children的渲染流似乎是冲突了。虽然页面能正常显示,这个warning也是提示我们最好不要这样做。
所以解决办法是把set state搬到useEffect中去,监测currentUser有值时再去做这个 set state.
const Layout: FC<PageProps> = ({loading, currentUser}) => {
useEffect(() => {
dispatch({
type: 'user/fetchCurrent'
});
}, []);
useEffect(() => {
if ( currentUser && dispatch ) {
dispatch({
type: 'user/setPermission',
payload: currentUser.permission.find(item.id == pid),
});
}
}, [currentUser]);
return <PageHeaderWrapper>{children}</PageHeaderWrapper>;
};