The React useEffect Hook has become a popular feature in the React library since its introduction in version 16.8. It enables developers to perform side effects such as fetching data, updating the DOM, and subscribing to events inside functional components.

However, the useEffect Hook can be tricky to use at times. One common error that developers encounter is the “React Hook useEffect has a missing dependency. Either include it or remove the dependency array” error.

In this article, we will discuss the causes of this error and provide various solutions on how to fix it.

What Causes the “React Hook useEffect Has a Missing Dependency” Error?

The “React Hook useEffect has a missing dependency” error occurs when the useEffect Hook has a dependency array that is incomplete or missing.

The dependency array is the second argument in the useEffect Hook and is used to specify the variables the effect depends on. This means when any of the values of the variables specified in the dependency array change, the effect is re-executed.

In a situation where a variable that the effect depends on is not included in the dependency array, the effect may not be re-executed when the value changes. This can lead to unexpected behavior and bugs in your application.

This error is not a React error but an ESLint error. ESLint provides a plugin specifically for React, which includes a set of rules that are designed to help developers write better React code. One of these rules is the "react-hooks/exhaustive-deps" rule, which detects the “React Hook useEffect has a missing dependency” error.

As an example, let’s look at a functional component that has a count state. This component also is expected to log a message with the value of count to the console whenever it changes:

import { useState, useEffect } from 'react';

const App = () => {
  const [count, setCount] = useState(0);

  useEffect(() => {
    console.log(`You clicked ${count} times`);
  }, []);

  return (
    <div>
      <h1>Hello World</h1>
      <p>Count: {count}</p>
      <button onClick={() => setCount(count + 1)}>Increment</button>
    </div>
  );
};

export default App;

In the above example, you have a functional component that uses the useState and useEffect hooks. The useEffect hook is used to log a message with the value of the count state variable whenever it changes.

However, notice that the count variable is not listed in the second argument array (dependency array) of the useEffect hook. This will trigger the “React Hook useEffect has a missing dependency” error.

React Hook useEffect has a missing dependency error message
React Hook useEffect has a missing dependency error message

 

3 Ways To Fix the “React Hook useEffect Has a Missing Dependency” Error

This error can be fixed in different ways depending on the approach you wish to use. Here are the various ways.

  • Include all missing dependencies
  • Use memoization hooks when working with objects and functions
  • Disable the ESLint rule

1. Add the Missing Dependency To the useEffect Dependency Array

The straightforward way to solve this error is to include all the dependencies used in the useEffect hook into the dependency array. Then you may ask how do I know a dependency?

To identify a missing dependency, you need to look at the variables or values that are used inside the useEffect hook. If any of these variables or values can change over time, then they should be included in the dependency array.

For example, in the code snippet provided earlier, the count variable is used inside the useEffect hook, but it is not included in the dependency array. This means that if the count variable changes, the useEffect hook will not be re-executed, and the component may have stale data or other issues.

To fix this error, we can add the count variable to the dependency array, like this:

import { useState, useEffect } from 'react';

const App = () => {
  const [count, setCount] = useState(0);

  useEffect(() => {
    console.log(`You clicked ${count} times`);
  }, [count]);

  return (
    <div>
      <h1>Hello World</h1>
      <p>Count: {count}</p>
      <button onClick={() => setCount(count + 1)}>Increment</button>
    </div>
  );
};

export default App;

By adding the count variable to the dependency array, we tell React to re-execute the useEffect hook whenever the count variable changes.

This ensures that the component always has up-to-date data and avoids the “React Hook useEffect has a missing dependency” error.

If you have more than one dependency, add them into the dependency array and separate them with a comma:

import { useState, useEffect } from 'react';
const App = () => {
  const [firstName, setFirstName] = useState('');
  const [lastName, setLastName] = useState('');
  const [fullName, setFullName] = useState('');

  useEffect(() => {
    setFullName(`${firstName} ${lastName}`);
  }, [firstName, lastName]);

  const handleFirstNameChange = (event) => {
    setFirstName(event.target.value);
  };

  const handleLastNameChange = (event) => {
    setLastName(event.target.value);
  };

  return (
    <div>
      <label>
        First Name:
        <input type="text" value={firstName} onChange={handleFirstNameChange} />
      </label>
      <label>
        Last Name:
        <input type="text" value={lastName} onChange={handleLastNameChange} />
      </label>
      <p>Full Name: {fullName}</p>
    </div>
  );
};

export default App;

2. Working With Objects and Functions

When working with objects and Arrays, it’s not enough to add them to your dependency array, you will need to either memoize them or move them into the useEffect hook or outside the component to avoid unnecessary re-renders.

This is because, in JavaScript, objects and arrays are compared by reference and point to a different location in memory every time — its value will change on every render, causing an infinite re-render loop.

Here is an example causing the error:

import { useState, useEffect } from 'react';

const App = () => {
  const [user, setUser] = useState({});

  // 👇️this will change on every render
  let newUser = { name: 'Jane', age: 28 };

  useEffect(() => {
    setUser(newUser);
  }, [newUser]);

  return (
    <div>
      <h1>Hello World</h1>
    </div>
  );
};

export default App;

You can fix this error by either moving the object into the useEffect hook or moving it outside the component:

import { useState, useEffect } from 'react';

const App = () => {
  const [user, setUser] = useState({});

  useEffect(() => {
    let newUser = { name: 'Jane', age: 28 };
    setUser(newUser);
  }, []);

  return (
    <div>
      <h1>Hello World</h1>
    </div>
  );
};

export default App;

A better way to solve this problem is to use memoization hooks like useMemo for your object and useCallback for functions. This will help you retain the object or function within the component and in the dependency array.

Note: Memoization hooks are a set of hooks that allow you to cache the results of expensive computations and avoid re-computing them unnecessarily.

This is what your code will look like when you use the useMemo hook to memoize your object:

import { useState, useEffect, useMemo } from 'react';

const App = () => {
  const [user, setUser] = useState({});

  const newUser = useMemo(() => {
    return { name: 'John', age: 30 };
  }, []);

  useEffect(() => {
    setUser(newUser);
  }, [newUser]);

  return (
    <div>
      <h1>Hello World</h1>
    </div>
  );
};

export default App;

Similarly, when working with functions, you can use the useCallback hook.

3. Disable the ESLint Rule

The “React Hook useEffect has a missing dependency” error is an ESLint warning error — meaning we can disable the rule so it doesn’t throw the error. This approach is not recommended in all cases, but it can be a quick fix if you are certain that the missing dependency is not a problem.

This can be done by adding the following comment before the dependency array’s line.

// eslint-disable-next-line react-hooks/exhaustive-deps

Here is an example:

useEffect(() => {
  console.log(`You clicked ${count} times`);
  
// eslint-disable-next-line react-hooks/exhaustive-deps
}, []);

It’s important to note that disabling the ESLint rule can lead to other issues in the future if you’re not careful. Ensure you thoroughly understand the consequences of disabling a rule before you do it and consider alternative solutions if possible.

Summary

The “React Hook useEffect has a missing dependency” error is a common issue faced by React developers when working with the useEffect hook.

When fixing the error, it’s important to consider the best methods for your specific use case. In general, it’s best to avoid disabling the ESLint rule causing the error, as this can lead to other issues in the future. Instead, try to address the issue by including the missing dependency in the dependency array or using the right memoization hook.

Now it’s your turn: Have you ever encountered this issue? How did you solve it? Are there any other approaches you used that is not covered in this article? Let us know in the comments!