首页 > 解决方案 > 对分配给 onClick 事件的 useReducer 的用法感到困惑

问题描述

我正在阅读此博客以更好地理解 React 的关键道具,作者使用的一个示例是


function Counter() {
  console.log('Counter called')
  const [count, setCount] = React.useState(() => {
    console.log('Counter useState initializer')
    return 0
  })
  const increment = () => setCount(c => c + 1)
  React.useEffect(() => {
    console.log('Counter useEffect callback')
    return () => {
      console.log('Counter useEffect cleanup')
    }
  }, [])
  console.log('Counter returning react elements')
  return <button onClick={increment}>{count}</button>
}
function CounterParent() {
  // using useReducer this way basically ensures that any time you call
  // setCounterKey, the `counterKey` is set to a new object which will
  // make the `key` different resulting in React unmounting the previous
  // component and mounting a new one.
  const [counterKey, setCounterKey] = React.useReducer(c => c + 1, 0)
  return (
    <div>
      <button onClick={setCounterKey}>reset</button>
      <Counter key={counterKey} />
    </div>
  )
}

我想我理解他使用reset按钮使key道具与众不同的部分。但是useReducer对我来说看起来很陌生。首先useReducer应该返回 a dispatch,在这种情况下我猜它是setCounterKey,然后它被传递给onClickprop。但我仍然不明白为什么这甚至有效。我们应该调用具有我们想要的动作类型和有效负载的对象吗?

我想知道他为什么不使用useState。我试图将代码修改为

const [counterKey, setCounterKey] = React.useState(0);

但我收到了这个错误

警告:出于性能原因,此合成事件被重用。如果您看到此内容,则表示您正在访问已movementY发布/无效合成事件的方法。这是一个无操作功能。如果您必须保留原始合成事件,请使用 event.persist()。

谁能给我解释一下?

标签: javascriptreactjs

解决方案


弹出此错误的原因是因为您将event对象传递给setCounterKey事件onClick

function CounterParent() {
  const [counterKey, setCounterKey] = React.useState(0);
  return (
    <div>
      // onClick={setCounterKey} will pass the event object to setCounterKey
     // onClick={(e => setCounterKey(e)} <-- `e` is event object

     // Instead use functional update like so
      <button onClick={() => setCounterKey(p => p + 1)}>reset</button>
      <Counter key={counterKey} />
    </div>
  );
}

这是一种不好的做法,警告本身和文档中解释了原因。

另一方面,使用useReducersetCounterKey已经使用回调调用 ( c => c + 1) 定义,因此事件未通过。

可以通过在此处useState查看示例来制作确切的示例。

编辑 Q-62560969-不要传递事件

我们应该调用具有我们想要的动作类型和有效负载的对象吗?

const [state, dispatch] = useReducer(reducer, initialArg, init);

不。传递一个对象type是一种常见的 Redux 模式。它确实令人困惑,但reducer功能可以是任何东西。参考useReducer文档


推荐阅读