reactjs - 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 等之后立即存储它......
欢迎任何关于如何做到这一点的想法。
解决方案
问题仍然是为什么 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 */
};
推荐阅读
- google-cloud-platform - What is easiest way to deploy using docker-compose.yml on GCP in 2018?
- haskell - 尝试在 Haskell 中构建树
- android - 为什么查询参数不使用 Retrofit2 android 编码
- hyperledger-composer - 如何在本地使用超级账本网卡
- php - 从 gmail 复制客户端数据并提交表单时 PHP 抛出 403 禁止错误
- php - 在 Drupal8 自定义块中使用自定义树枝模板
- c++ - Android 上 __property 的 Embarcadero C++Builder 错误
- ios - Xcode 10 - 构建和安装后未更新应用程序
- python-3.x - 带有迁移学习的自动编码器?
- java - 如何使用声明范围之外的对象?