从 for 循环中的多个连续异步调用调用多个 setState 挂钩
Call multiple `setState` hooks from multiple successive async calls in a for loop
我有以下功能性 React 组件:
const MyComp = (props) => {
const [dict, setDict] = useState({});
const myFunc = () => {
[1, 2, 3].forEach(x => {
fetch('something' + x)
.then(res => res.json())
.then(res => {
setDict({...dict, [x]: res.y}); // <-------- PROBLEMATIC HERE
})
});
}
}
似乎 React 正在对此进行预优化,所以我所有的 setDict
调用都被合并为一个。这意味着 dict
只有多个回调的一个任意结果。我怎样才能做到这一点?
问题
您正在使用标准更新在循环中对状态更新进行排队。这意味着每个更新都使用更新排队的渲染周期中的状态。每个后续更新都会覆盖先前的状态更新,因此最终结果是最后一个排队更新是为下一个渲染周期设置状态的更新。
解决方案
使用功能状态更新。这里的区别在于功能状态更新是从前一个状态更新的,而不是从前一个渲染周期更新的状态。它只需要从 setDict({...dict, [x]: res.y})
到 setDict(dict => ({...dict, [x]: res.y}))
的小调整。
const MyComp = (props) => {
const [dict, setDict] = useState({});
const myFunc = () => {
[1, 2, 3].forEach(x => {
fetch('something' + x)
.then(res => res.json())
.then(res => {
setDict(dict => ({...dict, [x]: res.y}));
})
});
}
}
setState
在回调的第一个参数中提供您所在州的当前值
因此使用来自回调参数的 dict
值而不是 dict
的状态值
const MyComp = (props) => {
const [dict, setDict] = useState({});
const myFunc = () => {
[1, 2, 3].forEach(x => {
fetch('something' + x)
.then(res => res.json())
.then(res => {
setDict((dict) => {...dict, [x]: res.y}); // <-------- PROBLEMATIC HERE
})
});
}
我有以下功能性 React 组件:
const MyComp = (props) => {
const [dict, setDict] = useState({});
const myFunc = () => {
[1, 2, 3].forEach(x => {
fetch('something' + x)
.then(res => res.json())
.then(res => {
setDict({...dict, [x]: res.y}); // <-------- PROBLEMATIC HERE
})
});
}
}
似乎 React 正在对此进行预优化,所以我所有的 setDict
调用都被合并为一个。这意味着 dict
只有多个回调的一个任意结果。我怎样才能做到这一点?
问题
您正在使用标准更新在循环中对状态更新进行排队。这意味着每个更新都使用更新排队的渲染周期中的状态。每个后续更新都会覆盖先前的状态更新,因此最终结果是最后一个排队更新是为下一个渲染周期设置状态的更新。
解决方案
使用功能状态更新。这里的区别在于功能状态更新是从前一个状态更新的,而不是从前一个渲染周期更新的状态。它只需要从 setDict({...dict, [x]: res.y})
到 setDict(dict => ({...dict, [x]: res.y}))
的小调整。
const MyComp = (props) => {
const [dict, setDict] = useState({});
const myFunc = () => {
[1, 2, 3].forEach(x => {
fetch('something' + x)
.then(res => res.json())
.then(res => {
setDict(dict => ({...dict, [x]: res.y}));
})
});
}
}
setState
在回调的第一个参数中提供您所在州的当前值
因此使用来自回调参数的 dict
值而不是 dict
const MyComp = (props) => {
const [dict, setDict] = useState({});
const myFunc = () => {
[1, 2, 3].forEach(x => {
fetch('something' + x)
.then(res => res.json())
.then(res => {
setDict((dict) => {...dict, [x]: res.y}); // <-------- PROBLEMATIC HERE
})
});
}