useReducer:即使状态未更改,调度也会导致重新呈现

时间:2019-10-01 15:09:46

标签: reactjs react-hooks

我注意到,如果我调度一个碰巧不修改状态的操作,则该组件仍将重新呈现。

示例:

// for simplicity sake, we simply pass state on (no mutation)
const someReducer = (state, action) => state

const App = () => {
  const [state, dispatch] = useReducer(someReducer, 0)

  // in my use case, I want to dispatch an action if some specific condition in state occurs
  if(state === 0) {
    dispatch({ type: 'SOME ACTION' })  // type doesn't matter
  }
  // return some JSX
}

我得到:

Error in app.js (16929:26)
Too many re-renders. React limits the number of renders to prevent an infinite loop.

这是设计使然吗?应该这样吗?

1 个答案:

答案 0 :(得分:2)

就您的示例而言,对于导致组件重新呈现的原因尚不立即清楚。但是,docs似乎暗示着,这并不保证在不改变状态时不会发生重新渲染:

  

请注意,React可能仍需要再次渲染该特定组件。不必担心,因为React不会不必要地“深入”到树中。如果渲染时要进行昂贵的计算,则可以使用useMemo对其进行优化。

这就是为什么通常建议您运行可能在useEffect中产生副作用的代码的原因,例如

const [state, dispatch] = useReducer(someReducer, 0);
...
useEffect(() => {
  if (state === 0) {
    dispatch({ type: 'SOME ACTION' });
  }
}, [state]);