1

假设以下示例:

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)
}
4

1 回答 1

1

您应该使用功能状态更新来访问和更新之前的状态。

功能更新

笔记

setState类组件中的方法不同,useState 它不会自动合并更新对象。您可以通过将函数更新程序形式与对象传播语法相结合来复制此行为:

const [state, setState] = useState({});
setState(prevState => {
  // Object.assign would also work
  return {...prevState, ...updatedValues};
});

使用承诺链

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
  ]);
}

根据实际的状态形状和result值,您的实际状态更新功能可能会根据您的具体需求而有所不同。

于 2021-10-12T06:27:23.620 回答