异步函数中的 setState
setState in async function
假设以下示例:
const example = () => {
const [objects, setObjects] = useState([])
const asyncFunction = async() => {
// This will trigger the API and assume it takes around 10 seconds to run
let result = api.fetchObjects().then((result) => {
// Here, setObjects will be called with the value it had at the moment the function started executing, not the actual value
setObjects(result)
}
}
}
我的问题是,执行 setObjects(result) 和使用更新状态的最佳方法是什么?假设用户可以在这 10 秒内通过应用程序中的不同方式将对象添加到该状态。
我找到了使用 useEffect 的解决方案,如下所示:
// Instead of setObjects(result)
const [updateObjects, setUpdateObjects] = useState(null)
setUpdateObjects(result)
useEffect(() => {
if (updateObjects !== null) {
setObjects(updateObjects)
setUpdateObjects(null)
}
您应该使用功能状态更新来访问和更新以前的状态。
Note
Unlike the setState
method found in class components, useState
does not automatically merge update objects. You can replicate this
behavior by combining the function updater form with object spread
syntax:
const [state, setState] = useState({});
setState(prevState => {
// Object.assign would also work
return {...prevState, ...updatedValues};
});
使用 Promise 链
const asyncFunction = () => {
api.fetchObjects()
.then((result) => {
setObjects(objects => [
...objects, // <-- shallow copy previous state array
result, // <-- append new state
]);
});
}
或使用async/await
const asyncFunction = async () => {
const result = await api.fetchObjects();
setObjects(objects => [
...objects, // <-- shallow copy previous state array
result, // <-- append new state
]);
}
根据 actual 状态形状和 result
值,您的实际状态更新功能可能看起来略有不同,具体取决于您的具体需求。
假设以下示例:
const example = () => {
const [objects, setObjects] = useState([])
const asyncFunction = async() => {
// This will trigger the API and assume it takes around 10 seconds to run
let result = api.fetchObjects().then((result) => {
// Here, setObjects will be called with the value it had at the moment the function started executing, not the actual value
setObjects(result)
}
}
}
我的问题是,执行 setObjects(result) 和使用更新状态的最佳方法是什么?假设用户可以在这 10 秒内通过应用程序中的不同方式将对象添加到该状态。
我找到了使用 useEffect 的解决方案,如下所示:
// Instead of setObjects(result)
const [updateObjects, setUpdateObjects] = useState(null)
setUpdateObjects(result)
useEffect(() => {
if (updateObjects !== null) {
setObjects(updateObjects)
setUpdateObjects(null)
}
您应该使用功能状态更新来访问和更新以前的状态。
Note
Unlike the
setState
method found in class components,useState
does not automatically merge update objects. You can replicate this behavior by combining the function updater form with object spread syntax:const [state, setState] = useState({}); setState(prevState => { // Object.assign would also work return {...prevState, ...updatedValues}; });
使用 Promise 链
const asyncFunction = () => {
api.fetchObjects()
.then((result) => {
setObjects(objects => [
...objects, // <-- shallow copy previous state array
result, // <-- append new state
]);
});
}
或使用async/await
const asyncFunction = async () => {
const result = await api.fetchObjects();
setObjects(objects => [
...objects, // <-- shallow copy previous state array
result, // <-- append new state
]);
}
根据 actual 状态形状和 result
值,您的实际状态更新功能可能看起来略有不同,具体取决于您的具体需求。