useReducer:即使状态没有改变,dispatch 也会导致重新渲染

Mic*_*icz 9 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
}

Run Code Online (Sandbox Code Playgroud)

我得到:

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

这是故意的吗?应该这样吗?

Jam*_*mes 8

就您的示例而言,导致组件重新渲染的原因并不是很明显。但是,文档似乎表明,当您不改变状态时,并不能保证不会发生重新渲染:

请注意,在退出之前,React 可能仍需要再次渲染该特定组件。这不应该是一个问题,因为 React 不会不必要地“深入”到树中。如果您在渲染时进行昂贵的计算,您可以使用 useMemo 优化它们。

这就是为什么通常建议您运行可能有副作用的代码,useEffect例如

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