useEffect, вызывающий бесконечный цикл с постоянной зависимостью - PullRequest
0 голосов
/ 31 октября 2019

useEffect запускается даже при том, что массив зависимостей имеет постоянный объект.

Я попытался извлечь логику и поместить объект в useState

const payload = {
    limit: 5,
    offset: 0,
    filterBy: 'All',
};

useEffect(() => {
    const defaultPayload = {
        limit: 10,
        offset: 0,
        filterBy: 'All',
    };
        dispatch({ type: RANDOM_CONST, payload: payload || defaultPayload });
}, [dispatch, payload]);

Это должно сработать толькокогда payload изменится. Поскольку payload является константой, она должна выполняться только один раз и отмечать бесконечное число раз.

Ответы [ 2 ]

5 голосов
/ 31 октября 2019

Есть две проблемы, которые могут вызвать повторную визуализацию, обратите внимание, что useEffect делает поверхностное сравнение со значениями dep-array:

  1. payload - это новый объект на каждом рендере, поэтому oldPayload === payload всегда false вызывает запуск useEffect.

  2. Если dispatchпоставляется из сторонней библиотеки (например, response-redux hook ), она может создавать новую ссылку dispatch при каждом рендеринге, поэтому снова oldDispatch === dispatch всегда false и вызывает запуск useEffect.

Чтобы исправить это, вы можете переместить «постоянный объект» во внешнюю область (который будет запущен один раз) и использовать хук useCallback, если вы передаете dispatch.

Пример из react-redux документы: При передаче обратного вызова с использованием dispatch для дочернего компонента рекомендуется запоминать его с помощью useCallback, так как в противном случае дочерние компоненты могут отображатьизлишне из-за измененного задания.

const payload = {
  limit: 5,
  offset: 0,
  filterBy: 'All'
};

const App = () => {
  //                   v Memoize it if passing as a callback,
  //                     check in library docs if there is a new instance
  //                     on every render
  const dispatch = useDispatch();

  useEffect(() => {
    dispatch({ type: RANDOM_CONST, payload });
  }, []);

  return;
};

Примечание. 1044 * функция приходит от.

0 голосов
/ 31 октября 2019

Вы можете преобразовать объекты в строки JSON и сравнить их внутри хука useEffect:

JSON.stringify(oldValue) === JSON.stringify(newValue) // true

Обратите внимание, что ключи объектов должны иметь одинаковый порядок:

JSON.stringify({a: 1, b: 2}) === JSON.stringify({a: 1, b: 2}) // true
JSON.stringify({a: 1, b: 2}) === JSON.stringify({b: 2, a: 1}) // false
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...