如何链接 React Context 调度?(钩子)

Jon*_*ger 3 reactjs react-hooks

我想要做的是订阅一个调度,然后调度到另一个状态。我试过 useEffect 但它给了我无限循环和一些谷歌搜索说不要更新 useEffect 的状态所以现在我的代码看起来像这样,但它没有按预期工作。

const Chain = () => {
  const [fooState, fooDispatch] = fooOne() // useReducer
  const [barState, barDispatch] = barTwo() // useReducer

  const btnOnClick = () => {
    fooDispatch({ type: "UPDATE_FOO" })

    // Update barState base on the new value of foo, doesn't work. 
    // Foo is not yet updated.
    if (fooState.value == 'new value') {
      barDispatch({ type: "UPDATE_BAR" }) 
    }
    // fooState gets updated after this function block.
  }

  return <Button label="Button" onClick={btnOnClick} />
}

export default Chain
Run Code Online (Sandbox Code Playgroud)

我的 useReducer 代码如下所示:https ://kentcdodds.com/blog/how-to-use-react-context-effectively

在线if (fooState.value == 'new value') {,React 仍然没有更新值,所以我不能进入 if 块。

bam*_*mse 5

我认为您应该使用useEffect2 个减速器挂钩保持同步。

钩子可以优化为仅在某些值更改时执行。在您的情况下,何时fooState.value(或者fooState如果您不想太严格)。

就像是:

React.useEffect(() => {
  if (fooState.value == 'new value') {
    barDispatch({ type: "UPDATE_BAR" }) 
  }
}, [fooState.value]);
Run Code Online (Sandbox Code Playgroud)

应该让你得到你想要的行为 - 也barDispatchbtnOnClick

执行顺序应该是这样的:

  1. 用户点击按钮,你调用 fooDispatch
  2. (foo)dispatch 更改fooState触发组件重新渲染的值
  3. 用于useEffectfooState更改时采取行动并调用barDispatch

如果fooOnebarTwo经常一起使用,也许您应该将它们组合在一个减速器钩子中。

我不知道你为什么不应该在useEffect. 这有点棘手,因为您可能会遇到无限循环,但在某些情况下您需要这样做。

我希望这有帮助!