How To Fix "react hook useeffect has a missing dependency"?
ESLint is a code analysis tool that helps prevent bugs and issues in your code. It works very well with React. Sometimes, however, while using the useEffect hook, you may get the "react hook useeffect has a missing dependency" warning.
To solve the "react hook useeffect has a missing dependency" warning, you can:
- Add the missing dependency
- Move the dependency inside the useEffect hook
- Disable the ESLint rule
This article will explore all of those options and show examples.
Let's get to it 😎.
Why does this warning happen?
First, let's understand why this warning happens.
This warning happens if the react-hooks/exhaustive-deps rule inside your ESLint configuration file is activated.
The react-hooks/exhaustive-deps rule verifies that every object declared outside a useEffect callback AND used by it is part of the dependency array.
If we use an outside object inside a useEffect BUT do not include it in the dependency array, we get a warning.
Here is an example of this warning:
javascriptimport React, { useEffect, useState } from "react";
import { createRoot } from "react-dom/client";
const App = () => {
const [value] = useState("value");
useEffect(() => {
console.log(value);
// Warning: React Hook useEffect has a missing
// dependency: 'value'. Either include it
// or remove the dependency array.
}, []);
return <div>{value}</div>;
};
const rootElement = document.getElementById("root");
const root = createRoot(rootElement);
root.render(<App />);
In this example, we use the value object inside the useEffect callback without putting it in the dependency array. That's why we get the warning.
Fix #1 - Add the missing dependency
The easiest method to fix the "react hook useeffect has a missing dependency" warning is to...
Add the missing dependency. That's why you got the error in the first place.
Let's fix the example from above by including the missing dependency:
javascriptimport React, { useEffect, useState } from "react";
import { createRoot } from "react-dom/client";
const App = () => {
const [value] = useState("value");
useEffect(() => {
console.log(value);
}, [value]);
return <div>{value}</div>;
};
const rootElement = document.getElementById("root");
const root = createRoot(rootElement);
root.render(<App />);
As you can see, you need to pass all the dependencies you are using, and the linter stops complaining.
Since the useEffect hook makes a comparison by reference for non-primitive types, their value is different on each render. That's why you must use special hooks around objects and functions used as dependencies:
- Use the useMemo hook around an object dependency.
- Use the useCallback hook around a function dependency.
Fix #2 - Move the dependency inside the useEffect
Another solution is to move the dependency inside the useEffect hook.
The downside of this solution is you cannot move a hook into a hook. So it is not possible to have a useState inside a useEffect hook. With non-hooks, however, this solution works great.
Here is how this solution works with a function:
javascriptimport React, { useEffect } from "react";
import { createRoot } from "react-dom/client";
const App = () => {
useEffect(() => {
const getValue = () => "value";
console.log(getValue());
}, []);
return <div></div>;
};
const rootElement = document.getElementById("root");
const root = createRoot(rootElement);
root.render(<App />);
In this example, if we didn't declare the getValue function inside the useEffect hook, we would need to pass the function as a dependency.
Fix #3 - Disable the ESLint rule
Finally, you can disable the ESLint rule for the line where the warning happens.
Here is how to do it:
javascriptimport React, { useEffect, useState } from "react";
import { createRoot } from "react-dom/client";
const App = () => {
const [value] = useState("value");
useEffect(() => {
console.log(value);
// eslint-disable-next-line react-hooks/exhaustive-deps
}, []);
return <div>{value}</div>;
};
const rootElement = document.getElementById("root");
const root = createRoot(rootElement);
root.render(<App />);
Note: You can also disable this rule for the whole file or project.
Final thoughts
As you can see, fixing this warning is easy.
I do not recommend disabling this warning but rather adding the missing dependency. Not adding it might cause logic fails and bugs. However, there are rare instances where disabling the rule is appropriate, so always double-check.
Here are some other React tutorials for you to enjoy: