Javascript 设置初始状态时为什么运行useHook?
我有一段数据由Javascript 设置初始状态时为什么运行useHook?,javascript,reactjs,react-hooks,Javascript,Reactjs,React Hooks,我有一段数据由useState()管理: 其思想是从一个端点加载一些基本信息,然后从另一个端点加载一些其他数据,然后将它们组合在一起以供进一步使用 我希望在启动时运行第一个请求,并且仅在数据未定义时运行下一个请求。 事实上,我看到console.log运行了两次-第一次使用undefined值,第二次使用第一次useffect调用加载的内容 这是正常行为还是我做错了什么,除了在loadSomeOtherData(data)调用中显式检查loadSomeOtherData(data)外,如何确保l
useState()管理:
其思想是从一个端点加载一些基本信息,然后从另一个端点加载一些其他数据,然后将它们组合在一起以供进一步使用
我希望在启动时运行第一个请求,并且仅在数据未定义时运行下一个请求。
事实上,我看到console.log
运行了两次-第一次使用undefined
值,第二次使用第一次useffect
调用加载的内容
这是正常行为还是我做错了什么,除了在loadSomeOtherData(data)
调用中显式检查loadSomeOtherData(data)外,如何确保loadSomeOtherData()。即使第二个钩子中的依赖项数组中有数据
,但它总是在装入后执行
现在,您不需要使用两个useffect
s来实现所需的行为。您可以在useffect
中使用异步函数,等待第一个数据完成,然后使用async继续第二个数据…等待或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
}, []);
这是正常行为,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()
})
}, []);
loadandSetData()。然后(()=>loadSomeOtherData())
?是的,这是React中的预期行为。(重点是我):当React渲染我们的组件时,它会记住我们使用的效果,然后在更新DOM后运行我们的效果。每次渲染都会发生这种情况,包括第一次渲染。
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()
})
}, []);