Inside of my useEffect, I have a props dependency (setIsValid). When I add this dependency to the useEffect, it lands in an infinite loop.
Parent when Calling Child Component:
const setIsValid = (bool) => {
const tmpStateCopy = Object.assign({}, state);
tmpStateCopy.isValid = bool;
setState(tmpStateCopy);
};
return <Child
setIsValid={setIsValid}
/>
In the Child Component:
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]);
This way the code works but I always get a warning.
What I want is, that the validation is always triggered when one of the values inside the state changes (transformations / duplicateIndexes).
By adding the setIsValid() func from the props, it runs infinitely.
The Warning looks like this:
./src/ponents/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
My question is, how can I keep the same logic without getting this warning?
Inside of my useEffect, I have a props dependency (setIsValid). When I add this dependency to the useEffect, it lands in an infinite loop.
Parent when Calling Child Component:
const setIsValid = (bool) => {
const tmpStateCopy = Object.assign({}, state);
tmpStateCopy.isValid = bool;
setState(tmpStateCopy);
};
return <Child
setIsValid={setIsValid}
/>
In the Child Component:
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]);
This way the code works but I always get a warning.
What I want is, that the validation is always triggered when one of the values inside the state changes (transformations / duplicateIndexes).
By adding the setIsValid() func from the props, it runs infinitely.
The Warning looks like this:
./src/ponents/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
My question is, how can I keep the same logic without getting this warning?
Share Improve this question edited Jun 23, 2019 at 6:47 skyboyer 23.8k7 gold badges62 silver badges71 bronze badges asked Jun 11, 2019 at 12:08 EmreEmre 1531 gold badge2 silver badges10 bronze badges1 Answer
Reset to default 4Since, when state changes you will call the effect. transformations and duplicateIndexes will already be considered for. To avoid the warning, you can move the destructure
within 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]);
Also regarding setIsValid as a dependency to useEffect, you must not do that since a new function for it is created on every render and it will cause the useEffect to to run again and again unles you refactor your code a bit.
const setIsValid = useCallback((bool) => {
setState(prev => Object.assign({}, prev, {isValid: bool});
}, []);
and now you can set setIsValid
as a dependency.