为了账号安全,请及时绑定邮箱和手机立即绑定

在孩子的第一次渲染 useEffect 上用旧状态反应钩子 useState

在孩子的第一次渲染 useEffect 上用旧状态反应钩子 useState

ABOUTYOU 2023-08-05 21:12:50
示例: https: //codesandbox.io/s/react-hooks-playground-forked-15ctx ?file=/src/index.tsx一名父级具有 1 个 useState 挂钩,3 个子级具有 1 个 useEffect 挂钩。我希望子级通过回调更新父级中的状态,以便所有组件状态都更新为父级中的一个对象。这不适用于初始/第一次渲染,因为当前状态不会在每个 useEffect 触发的回调之间更新(请参见上面的示例或下面的代码)。这意味着组合状态仅包含最后一个子级的状态。const ChildElement = ({ index, callback }) => {  useEffect(() => {    callback(index);  }, []);  return <>{index}</>;};const App = () => {  const [state, setState] = useState(0);  const callback = (index: any) => {    const newObject = { a: index };    setState({ ...state, [index]: newObject });  };  console.log(state);  return (    <>      <ChildElement index={0} callback={callback} />      <ChildElement index={1} callback={callback} />      <ChildElement index={2} callback={callback} />    </>  );};我可以在父级中声明初始状态,但这需要更多代码我可以在渲染缓存中使用(我像 useStae 一样手动更新的对象,但立即更改),但这感觉很脏钩子 useReducer 是一个好的解决方案吗?有什么建议么?解决这个问题的最佳方法是什么?
查看完整描述

1 回答

?
慕容708150

TA贡献1831条经验 获得超4个赞

你面临着竞争条件。


如果你改变


const callback = (index: any) => {

    const newObject = { a: index };

    setState({ ...state, [index]: newObject });

  };

到:


  const callback = (index: any) => {

    const newObject = { a: index };

    setState((currentState) => ({ ...currentState, [index]: newObject }));

  };


你的代码会起作用


虽然这样:


所有组件状态都更新为父级中的一个对象


这不是一个好的做法。


更好的子组件拥有自己的状态,如果这些状态彼此相似,您可以通过创建自定义挂钩来减少代码。


查看完整回答
反对 回复 2023-08-05
  • 1 回答
  • 0 关注
  • 69 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信