我有一个由useState()
管理的数据:
const [data, setData] = useState() // undefined as the initial state
useEffect(() => {
loadandSetData(setData) // some fetch then running setData to change data object
}, []);
useEffect(() => {
console.log('Will request additional data...')
console.log(data)
loadSomeOtherData() // Should be executed only when data turns from undefined to something
}, [data]);
这个想法是从一个端点加载一些基本信息,然后从另一个端点加载一些其他数据,然后将它们组合在一起以供进一步使用。
我想在启动时运行第一个请求,仅在数据不是undefined
时才运行下一个请求。
实际上,我看到console.log
运行了两次-第一次运行时带有undefined
值,第二次运行时加载了第一次useEffect
调用。
这是正常行为还是我做错了什么?除了明确检查loadSomeOtherData()
内部的内容之外,data
对象中有什么内容时,如何确保loadSomeOtherData(data)
运行打电话?
答案 0 :(得分:0)
这是正常现象。即使第二个挂钩中的依赖项数组内部有data
,也始终在装入后执行。
现在,您无需使用两个useEffect
即可拥有所需的行为。您可以在useEffect
中使用异步功能,并等待第一个数据完成,然后使用async...await
或Promise.then()
(以您喜欢的为准)继续第二个数据
类似的东西:
const [data, setData] = useState() // undefined as the initial state
useEffect(async () => {
const someData = await loadandSetData() // this returns a promise that resolves with the data retrieved (i.e a fetch()) - change name of variable
// here you already have someData
const someOtherData = await loadSomeOtherData(); // same as above
// here you already have someOtherData
setData([...someData, ...someOtherData]); // supposing both are array objects and you want to concat them using the spread operator
}, []);
答案 1 :(得分:0)
这是正常的行为,useEffect会在每个渲染(包括初始渲染)之后运行。但是,您应该更改useEffect的使用方式,以获取所需的行为。
useEffect(() => {
if (data !== undefined) {
// now the following will only execute when data is not undefined
console.log('Will request additional data...')
console.log(data)
loadSomeOtherData()
}
}, [data])
另一个选择是调用loadSomeOtherData的效果与loadAndSetData相同
useEffect(() => {
// seems from the signature of how you used loadAndSetData that it takes a callback with a data object, so you could do this
loadandSetData(data => {
setData(data)
loadSomeOtherData()
})
}, []);