This warning means that I have not included all the variables I use in the useEffect
hook in the dependency array, and the useEffect
hook may not function as intended.
Let's take a look at the different variations of the useEffect
hook.
useEffect hook without dependency array
The useEffect
hook without a dependency array runs every time the component re-renders. That is equivalent to the componentDidUpdate()
lifecycle hook in class components.
useEffect(() => {
console.log("some text") //executes in every component re-render
})
That may not be necessary and may negatively impact performance.
useEffect hook with empty dependency array
I can control the useEffect
hook's execution by adding a dependency array. The useEffect
hook with an empty dependency array runs only when the component initially mounts. That is equivalent to the componentDidMount()
lifecycle hook in class components.
useEffect(() => {
console.log("some text") //executes only when the component initially mounts
},[])
Now, what if I use a state variable inside the useEffect
hook? The below hook will run when the component mounts. After that, any changes to the text variable will not affect this hook. The if(text){
condition may never be executed.
useEffect(() => {
if(text){
console.log(text)
}
}, [])//React Hook useEffect has a missing dependency warning
useEffect hook with dependencies in the dependency array
I can overcome this limitation by including the text variable in the dependency array. In that way, my useEffect
will run whenever the text state variable changes its value. Here is the complete code example to demonstrate that.
import { useEffect, useState } from "react";
const App = () => {
const [text, setText] = useState<string>("")
useEffect(() => {
if(text){
console.log(text)//runs when text changes
}
}, [text])
return (
<div>
<textarea onChange={(e) => setText(e.target.value)}></textarea>
</div>
);
}
export default App;
The same rules apply when I use props inside my useEffect
hook. The hook must know when to re-render when the props change. Otherwise, the useEffect
hook ends up with stale variables that can lead to unexpected behavior.
In the below code, the useEffect
runs when the component mounts. Then it is unaware of any changes to the props.text
.
useEffect(() => {
if(props.text){
console.log(props.text)
}
}, []) //React Hook useEffect has a missing dependency warning
I can solve that potential issue by adding the props.text
to the dependency array.
useEffect(() => {
if(props.text){
console.log(props.text)
}
}, [props.text])