将useState钩子上的先前状态与新状态合并的正确流程是什么?

时间:2020-07-16 22:30:57

标签: javascript reactjs ecmascript-6

假设我的初始状态是这样:

  let initialStoreState = {
    products: [],
    checkout: [],
    adding: false,
    loading: true
  }

  const [store, updateStore] = useState(initialStoreState)

  useEffect(() => {
    if(someValue) {
        // pay attention to this code below
        updateStore((prevState) => {
          return { ...prevState, checkout, loading: false }
        })
    }
  }, [someValue]}

所以您会像在updateStore上那样使用它吗?

// this is how I normally see it being used
updateStore({ ...store, checkout, loading: false })

一个或另一个是否存在任何差异或可变性问题?

1 个答案:

答案 0 :(得分:0)

如果问题是有关使用功能更新还是直接使用状态值更新状态,则在大多数情况下,直接更新状态将起作用。

// will work most of the times
updateStore({ ...store, checkout, loading: false })

但是很容易遇到由于关闭而导致捕获过时状态值的问题。最简单的示例是,如果传递给setTimeoutsetInterval的回调试图直接更新状态值,则可能不会产生预期的结果。

要解决关闭问题,我们可以使用functional updates

// example from the current use case
updateStore((prevState) => {
    return { ...prevState, checkout, loading: false }
})

下面是一个示例codesandbox,其中介绍了关闭问题。

但是,对于您当前的用例useReducer似乎更合适,这是管理带有多个子值的状态对象的建议方法。