Внутри моего 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.info('got triggered');
}, [state]);
Таким образом, код работает, но я всегда получаю предупреждение.
Я хочу, чтобы проверка всегда запускалась при изменении одного из значений внутри состояния (преобразования/дубликаты индексов).
Добавляя функцию 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
Мой вопрос: как я могу сохранить ту же логику, не получая этого предупреждения?



![Безумие обратных вызовов в javascript [JS]](https://i.imgur.com/WsjO6zJb.png)


Так как при изменении состояния вы вызовете эффект. преобразования и дубликаты индексов уже будут рассмотрены. Чтобы избежать предупреждения, вы можете переместить 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.info('got triggered');
}, [state]);
Кроме того, рассматривая setIsValid как зависимость от useEffect, вы не должны этого делать, поскольку новая функция для него создается при каждом рендеринге, и это приведет к тому, что useEffect будет запускаться снова и снова, если вы немного не реорганизуете свой код.
const setIsValid = useCallback((bool) => {
setState(prev => Object.assign({}, prev, {isValid: bool});
}, []);
и теперь вы можете установить setIsValid в качестве зависимости.
Обновлен мой ответ
Вы также можете добавить props.setIsValid в качестве зависимости напрямую, без деструктурирования.
Спасибо за быстрый ответ. Это правильно, но у меня все еще есть проблема с реквизитом setIsValid, так как он все еще требует это как зависимость. Любые идеи, как я могу обойти это?