在 useEffect 中处理 forEach 后调用 setstate
Calling setstate after processing forEach within useEffect
我试图在 useEffect 上处理一些 api 数据,在处理数据时我需要将其设置为各种状态,在处理数据时,由于某些原因 useEffect 被无限触发。虽然从 class 组件我知道 setState 是一个异步操作,它不等待 forEach 的完成。我们有功能组件的解决方法吗?
useEffect(() => {
const apiResponse = fetchAppName();
apiResponse.then(
(response) => {
// if (response.statusCode === '200' && response.status.statusType === 'SUCCESS' && response.data) {
const dataFields = {};
const appNameValues = [];
dummyData.data.forEach((ele) => {
const workFlowIds = [];
ele.workflowConfigs.forEach((wc) => {
workFlowIds.push(wc.workflowId);
})
dataFields[ele.name] = workFlowIds;
});
Object.keys(dataFields).forEach((k) => {
appNameValues.push(k);
});
setAppData(dataFields);
setDropDownOptions({
...dropDownOptions,
appName: appNameValues,
});
// }
}).catch((e)=>{
console.log('Failed to fetchAppNames due to: ', e);
});
},[setDropDownOptions, dropDownOptions]);
问题
不要使用由效果更新的依赖项。换句话说,dropDownOptions
是一个依赖项,效果会更新它,从而创建一个渲染循环。
解决方案
state updater 函数是稳定的,所以它是不必要的,并且使用一个功能性的 state update 来移除另一个 dropDownOptions
依赖。
Note
React guarantees that setState function identity is stable and won’t
change on re-renders. This is why it’s safe to omit from the useEffect
or useCallback dependency list.
useEffect(() => {
const apiResponse = fetchAppName();
apiResponse.then(
(response) => {
// if (response.statusCode === '200' && response.status.statusType === 'SUCCESS' && response.data) {
const dataFields = {};
const appNameValues = [];
dummyData.data.forEach((ele) => {
const workFlowIds = [];
ele.workflowConfigs.forEach((wc) => {
workFlowIds.push(wc.workflowId);
})
dataFields[ele.name] = workFlowIds;
});
Object.keys(dataFields).forEach((k) => {
appNameValues.push(k);
});
setAppData(dataFields);
setDropDownOptions(dropDownOptions => ({
...dropDownOptions,
appName: appNameValues,
}));
// }
}).catch((e)=>{
console.log('Failed to fetchAppNames due to: ', e);
});
},[]); // will run on mount, add other dependency triggers if needed.
我试图在 useEffect 上处理一些 api 数据,在处理数据时我需要将其设置为各种状态,在处理数据时,由于某些原因 useEffect 被无限触发。虽然从 class 组件我知道 setState 是一个异步操作,它不等待 forEach 的完成。我们有功能组件的解决方法吗?
useEffect(() => {
const apiResponse = fetchAppName();
apiResponse.then(
(response) => {
// if (response.statusCode === '200' && response.status.statusType === 'SUCCESS' && response.data) {
const dataFields = {};
const appNameValues = [];
dummyData.data.forEach((ele) => {
const workFlowIds = [];
ele.workflowConfigs.forEach((wc) => {
workFlowIds.push(wc.workflowId);
})
dataFields[ele.name] = workFlowIds;
});
Object.keys(dataFields).forEach((k) => {
appNameValues.push(k);
});
setAppData(dataFields);
setDropDownOptions({
...dropDownOptions,
appName: appNameValues,
});
// }
}).catch((e)=>{
console.log('Failed to fetchAppNames due to: ', e);
});
},[setDropDownOptions, dropDownOptions]);
问题
不要使用由效果更新的依赖项。换句话说,dropDownOptions
是一个依赖项,效果会更新它,从而创建一个渲染循环。
解决方案
state updater 函数是稳定的,所以它是不必要的,并且使用一个功能性的 state update 来移除另一个 dropDownOptions
依赖。
Note
React guarantees that setState function identity is stable and won’t change on re-renders. This is why it’s safe to omit from the useEffect or useCallback dependency list.
useEffect(() => {
const apiResponse = fetchAppName();
apiResponse.then(
(response) => {
// if (response.statusCode === '200' && response.status.statusType === 'SUCCESS' && response.data) {
const dataFields = {};
const appNameValues = [];
dummyData.data.forEach((ele) => {
const workFlowIds = [];
ele.workflowConfigs.forEach((wc) => {
workFlowIds.push(wc.workflowId);
})
dataFields[ele.name] = workFlowIds;
});
Object.keys(dataFields).forEach((k) => {
appNameValues.push(k);
});
setAppData(dataFields);
setDropDownOptions(dropDownOptions => ({
...dropDownOptions,
appName: appNameValues,
}));
// }
}).catch((e)=>{
console.log('Failed to fetchAppNames due to: ', e);
});
},[]); // will run on mount, add other dependency triggers if needed.