【问题标题】:Confused about the usage of useReducer assigned to onClick event对分配给 onClick 事件的 useReducer 的用法感到困惑
【发布时间】:2020-06-24 17:41:32
【问题描述】:

我阅读这篇博客是为了更好地理解 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 应该返回一个dispatch,在这种情况下我猜它是setCounterKey 然后它被传递给onClick prop。但我仍然不明白为什么这甚至有效。我们是否应该使用具有我们想要的操作类型和有效负载的对象调用 dispatch?

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

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

但我收到了这个错误

警告:出于性能原因,会重复使用此合成事件。如果你看到这个,你正在访问方法movementY 在一个释放/无效的合成事件上。这是一个无操作功能。如果您必须保留原始合成事件,请使用 event.persist()。

谁能给我解释一下?

【问题讨论】:

    标签: javascript reactjs


    【解决方案1】:

    弹出这个错误的原因是因为你在onClick事件上将event对象传递给setCounterKey函数:

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

    这是一种不好的做法,原因在警告中解释,in the docs

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

    可以使用useState 制作确切的示例,参见example here

    我们是否应该使用具有我们想要的操作类型和有效负载类型的对象调用调度?

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

    没有。使用 type 传递对象是常见的 Redux 模式。它确实令人困惑,但reducer 函数可以是任何东西。参考useReducer in docs

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-11-12
      • 1970-01-01
      • 1970-01-01
      • 2012-09-18
      • 1970-01-01
      • 2021-11-16
      • 1970-01-01
      相关资源
      最近更新 更多