我正在尝试将一些旧的componentDidMount代码迁移到新的useEffect钩子上,并且在弄清楚如何模拟setState的回调行为时遇到问题
我有一系列从api中提取的东西,我只需要在状态和加载后调用一个函数,然后才调用一次
先前的代码:
ComponentDidMount() {
const response = await getMyArrayFromAPI
this.setState({ myArray }, () => { initializeArray() })
}
当前代码:
const [myArray, setMyArray] = useState([])
useEffect(() = {
const response = await getMyArrayFromAPI
setMyArray(response)
}, [])
useEffect(() => {
// one time initialization of data
// initially gets called before myArray has value, when it should be after
// gets called every time myArray changes, instead of only once
}, [myArray])
答案 0 :(得分:0)
您可以在第一个myArray
函数中设置useEffect
,但如果要使用单独的函数,则只需检查其是否为空
useEffect(() => {
if (!myArray.length) {
// one time initialization
}
}, [myArray])
答案 1 :(得分:0)
您可以使用状态来驱动initializeArray
是否需要运行,例如
const [array, setArray] = useState(null);
useEffect(() => {
getMyArrayFromAPI.then(data => setArray(data || []));
}, []);
if (array) {
// this will only ever run once as we don't set `array`
// anywhere other than `useEffect`
initializeArray();
}
根据initializeArray
的实际操作,您可以从then
内部运行它,但这完全取决于您。
答案 2 :(得分:0)
我想您可以创建一个自定义setState挂钩来管理您的回调
const useMyCustomStateHook = (initState, cb) => {
const [customState, updateCustomState] = useState(initState);
useEffect(() => cb(customState), [customState, cb]);
return [customState, updateCustomState];
};
这样您就可以拥有
import React, {useState,useEffect} = from 'react'
const [myArray, setMyArray] = useMyCustomStateHook([], initializeArray)
useEffect(() = {
const response = await getMyArrayFromAPI
setMyArray(response)
}, [])