useReducer: отправка вызывает повторное рендеринг, даже если состояние не изменилось - PullRequest
0 голосов
/ 01 октября 2019

Я заметил, что если я отправляю действие, которое не изменяет состояние, компонент все равно перерисовывается.

Пример:

// 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 Ответ

2 голосов
/ 01 октября 2019

С точки зрения вашего примера как есть, не сразу очевидно, что вызывает повторную визуализацию компонента. Тем не менее, документы , по-видимому, предполагают, что это не гарантия того, что повторный рендеринг не произойдет, если вы не изменили состояние:

Обратите внимание, чтоReact, возможно, по-прежнему нужно будет визуализировать этот конкретный компонент еще раз перед спасением. Это не должно вызывать беспокойства, поскольку React не будет излишне углубляться в дерево. Если вы выполняете дорогостоящие вычисления во время рендеринга, вы можете оптимизировать их с помощью useMemo.

Именно поэтому обычно рекомендуется запускать код, который может иметь побочные эффекты в useEffect, например,

const [state, dispatch] = useReducer(someReducer, 0);
...
useEffect(() => {
  if (state === 0) {
    dispatch({ type: 'SOME ACTION' });
  }
}, [state]);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...