React Hooks useEffect, добавление зависимостей запускает бесконечный цикл - PullRequest
4 голосов
/ 11 июня 2019

Внутри моего useEffect у меня есть зависимость от реквизита (setIsValid).Когда я добавляю эту зависимость в useEffect, она попадает в бесконечный цикл.

Родитель при вызове дочернего компонента:

const setIsValid = (bool) => {
  const tmpStateCopy = Object.assign({}, state);
  tmpStateCopy.isValid = bool;

  setState(tmpStateCopy);
};

return <Child
  setIsValid={setIsValid}
/>

В дочернем компоненте:

const { setIsValid } = props;

const [state, setState] = useState({
  transformations: [],
  duplicateIndexes: []
});

const { transformations, duplicateIndexes } = state;

useEffect(() => {
  const invalids = transformations.find(x => (x.value === '' || x.replaceWith === ''));
  const hasDuplicates = duplicateIndexes.length > 0;
  const isValid = ((invalids === undefined) && (transformations.length > 0) && !hasDuplicates);

  setIsValid(isValid)

  console.log('got triggered');
}, [state]);

Таким образом, код работает, но я всегда получаю предупреждение.

Я хочу, чтобы проверка всегда запускалась при изменении одного из значений внутри состояния (transformation / duplicateIndexes).

Добавляя функцию setIsValid () из реквизита, он работает бесконечно.

Предупреждение выглядит так:

./src/components/UI/integrationBuilder/layoutElements/transformer/modules/ifModules/ifModule.js
  Line 103:  React Hook useEffect has missing dependencies: 'duplicateIndexes.length', 'setIsValid', and 'transformations'. Either include them or remove the dependency array  react-hooks/exhaustive-deps

Мой вопрос заключается в том, как сохранить ту же логику, не получаяэто предупреждение?

1 Ответ

1 голос
/ 11 июня 2019

Так как при изменении состояния вы будете вызывать эффект.преобразования и duplicateIndexes уже будут рассмотрены для.Чтобы избежать предупреждения, вы можете переместить destructure в пределах useEffect

const { setIsValid } = props;

const [state, setState] = useState({
  transformations: [],
  duplicateIndexes: []
});



useEffect(() => {
  const { transformations, duplicateIndexes } = state;
  const invalids = transformations.find(x => (x.value === '' || x.replaceWith === ''));
  const hasDuplicates = duplicateIndexes.length > 0;
  const isValid = ((invalids === undefined) && (transformations.length > 0) && !hasDuplicates);

  setIsValid(isValid)

  console.log('got triggered');
}, [state]);

Также относительно setIsValid как зависимости от useEffect, вы не должны этого делать, так как новая функция для него создается на каждом рендере.и это заставит useEffect to запускаться снова и снова, чтобы вы немного реорганизовали свой код.

const setIsValid = useCallback((bool) => {
  setState(prev =>  Object.assign({}, prev, {isValid: bool});
}, []);

, и теперь вы можете установить setIsValid в качестве зависимости.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...