首页 > 解决方案 > setState 不异步更新

问题描述

这是一个使用反应钩子的功能反应组件 - 状态以一种奇怪的方式更新,破坏了我的组件流程。关于为什么会发生这种情况以及如何可靠地更新子组件所需的状态的任何想法。目前,我的firestore保存不起作用,因为它需要用户ID,并且由于更新滞后而无法从状态中获取它...

const XYZ = (props) => {

  const [data, setData] = useState({
    ...props,
  });

  const getinitdata = async () => {
    let user = await utils.getUser();
    console.log("1", user.uid); //USERID
    await setData({ ...data, uid: user.uid });
    console.log("3", data.uid); //UNDEFINED
  }

  useEffect(() => {
    console.log("componentDidMount");
    getinitdata();
    console.log("2", data.uid); //UNDEFINED
    return () => {
      console.log("componentWillUnmount");
    };
  }, []); // empty-array means don't watch for any updates

  console.log("4", data.uid); //USERID

  return (

    <div>{data.uid}</div>


  );
}

上面的 console.log 打印如下:

componentDidMount
2 undefined
1 KMDTFXxktUTwq6Kg34l8r5qWkAL
4 KMDTFXxktUTwq6Kg34l8r5qWkAL
3 undefined

目标只是确保 setData 通过添加一些数据来更新状态,比如这里的 uid。所以使用状态作为临时存储。

然后,该数据应该可用,以防某个函数需要将其写入数据库,作为诸如预订之类的事务的一部分。

我发现与基于类的 this.setState({smth:smth}) 完全不同,我可以依靠它来立即更新状态,不能依赖功能性的 - 例如,这不t 更新状态 setData({...data, smth:smth}) 以使 data.smth 为非空并准备好发送。

这消除了 this.setState 功能,并且不确定使用什么解决方法来获取状态以在 var 可用、uid 等之后立即存储它......

欢迎任何关于如何做到这一点的想法。

标签: reactjsreact-hooks

解决方案


问题仍然是为什么 console.log("3", data.uid); 尽管在 setData 之前等待,但未定义。

您的箭头函数 inuseEffect 捕获data变量,并且调用setData不会更新该函数中的值,data无论您是否使用await. 怎么可能?data被声明const,所以任何看到它的东西都会得到初始值。调用的目的是在下一次重新渲染setData时获得一个新的值。data

如果您想要一个值,您可以更改useEffect并在之后立即读取,使用const data = useRef该字段并将其更改为data.current您想要的值。

PS,你通常不应该将 props 复制到 state

编辑:提供的例子

const XYZ = props => {
  const data = useRef(null);
  useEffect(() => {
    const fn = async () => {
      data.current = 1;
      await delay(1000);
      data.current = 2;
      console.log(data.current); // 2
    };
    fn();
  }, []);
  return /* whatever */
};

推荐阅读