首页 > 解决方案 > 在 useState 挂钩上将先前状态与新状态合并的正确流程是什么?

问题描述

假设我的初始状态有这个:

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

两者之间是否存在任何差异或可变性问题?

标签: javascriptreactjsecmascript-6

解决方案


如果问题是使用函数更新还是直接使用状态值来更新状态,大多数情况下直接更新状态是可行的。

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

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

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

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

这是一个示例代码框,其中演示了关闭问题。

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


推荐阅读