I have a dropdown menu which has a controlled state. If the user changed the dropdown value and if the input is not empty, fire a function passed from other component.
export default ({ triggerChange, inputVal }) => {
const [dropdown, setDropdown] = useState(1);
useEffect(() => {
if (inputVal) {
triggerChange(dropdown);
}
}, [dropdown]); // this line throw a warning
const handleChange = e => {
setDropdown(e.target.value);
};
return (
<div>
<select onChange={handleChange}>
<option value="1">1</option>
<option value="2">2</option>
</select>
</div>
);
};
codesandbox
Error
React Hook useEffect has missing dependencies: 'inputVal' and 'triggerChange'. Either include them or remove the dependency array. If 'triggerChange' changes too often, find the parent component that defines it and wrap that definition in useCallback. (react-hooks/exhaustive-deps)
Add those to the dependency:
useEffect(() => {
if (inputVal) {
triggerChange(dropdown);
}
}, [dropdown, inputVal]);
This will only re-run the effect if either dropdown
or inputVal
values change.
For triggerChange
:
if dropdown
changes frequently, use useCallback
hook.
// Parent.js
const memoizedTriggerChange = useCallback(
() => {
triggerChange(dropdown);
},
[dropdown],
);
useEffect(() => {
if (inputVal) {
memoizedTriggerChange();
}
}, [inputVal]);
EDIT
based on the OPs codesandbox
// index.js
const triggerChange = useCallback(() => {
console.log("call api");
}, []); // not depending on inputVal to prevent firing if inputVal changes
// AnotherComp.js
useEffect(() => {
triggerChange(dropdown);
}, [dropdown, triggerChange]);
useEffect(() => {
if (inputVal) {
triggerChange(dropdown);
}
}, [dropdown]); // this line throw a warning
In this piece of code, if you notice, inputVal
, triggerChange
and dropdown
are variables and they are dependencies to useEffect hook because useEffect gets triggered whenever any change is made to any of the aforementioned dependencies.
To satisfy the basic working principle of useEffect hook, we should pass those depdencies in useEffect's array parameter.
useEffect(() => {
if (inputVal) {
triggerChange(dropdown);
}
}, [dropdown, triggerChange, inputVal]);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With