Why we use empty array with UseEffect
Clara Situma

Clara Situma @csituma

About: i love technology I love simplifying complex topics.,and solving problems

Location:
Nairobi
Joined:
Sep 25, 2020

Why we use empty array with UseEffect

Publish Date: Dec 8 '22
26 18

If you do not pass an empty array as an argument to useEffect,
the effect will run on every render of the component.

This means that any code inside the useEffect callback will be executed on initial render, and on subsequent updates to the component.

Here is an example of using useEffect without an empty array:


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

function MyComponent() {
  const [data, setData] = useState(null);

  useEffect(() => {
    // This will run on every render of the component
    fetchData().then(response => setData(response));
  });

  return (
    // component render code here
  );
}

Enter fullscreen mode Exit fullscreen mode

In this example, useEffect is used to fetch data from an API on every render of the component. This means that the fetchData function will be called o*n initial render, and **on every subsequent update to the component.*

This can lead to unnecessary network requests and can negatively impact the performance of your application.

If you do not want the useEffect callback to run on every render, you should pass an empty array as an argument to useEffect.

This tells React that the effect does not depend on any values from the component's props or state, so it only needs to be run once on initial render.

Here is an example of using useEffect with an empty array:


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

function MyComponent() {
  const [data, setData] = useState(null);

  useEffect(() => {
    // This will only run on initial render
    fetchData().then(response => setData(response));
  }, []);

  return (
    // component render code here
  );
}
Enter fullscreen mode Exit fullscreen mode

In this example, useEffect is used to fetch data from an API when the component is first rendered.

The empty array as an argument to useEffect means that the fetchData function will only be called on initial render, and not on subsequent renders when the data state changes.

This helps to avoid unnecessary network requests and can improve performance.

Comments 18 total

  • Rense Bakker
    Rense BakkerDec 8, 2022

    Bonus points if you also add a cleanup to your useEffect, to cancel the request when the component gets unmounted during fetching. In your current code the state update will produce an error if the component gets unmounted during fetching (cant update state of unmounted component).

    • Clara Situma
      Clara SitumaDec 8, 2022

      what do you think about this dev.to/csituma/do-i-need-to-use-cl...

      • Rense Bakker
        Rense BakkerDec 9, 2022

        I mostly agree with that, except that you should also cleanup if you do delayed state updates in your useEffect, to avoid updating state on unmounted components (which will result in an error).

    • Clara Situma
      Clara SitumaDec 9, 2022

      Thank you, that's a great addition

  • Ritik Banger
    Ritik BangerDec 9, 2022

    Providing no dependency in the useEffect give sideEffects and introduce bugs. Always, Always give the dependencies required by useEffect. By using empty array you can get your desired result but it will definitely introduce bug and hard to maintain the code in long run.

    • Clara Situma
      Clara SitumaDec 9, 2022

      This is correct.

      However in instances where there are no dependencies, an empty array is okay,
      Don't you agree?

      • Ritik Banger
        Ritik BangerDec 9, 2022

        Could you give an example where the instance does not have any dependency? Even if you use a variable/function, you have to give a dependency.

        • Clara Situma
          Clara SitumaDec 9, 2022

          Hmm...

          A simple fetch?

          useEffect(() => {
          fetch("pokeapi.co/api/v2/type/3")
          }, []);

          • Ritik Banger
            Ritik BangerDec 9, 2022

            In this example, the useEffect will ask for the dependency of fetch function.

            The corrected code:

            useEffect(() => {
            fetch("pokeapi.co/api/v2/type/3")
            }, [fetch]);
            
            Enter fullscreen mode Exit fullscreen mode

            If you use the empty array as a dependency and if you have any linter, you will surely get an error/warning based on the setup.

            • Clara Situma
              Clara SitumaDec 9, 2022

              In your example, using fetch as dependency is unnecessary and will infact bring up a warning(mutating it can't cause a re-render because it will be recognised as an Outer scope value )

              You should try run the code

              • Ritik Banger
                Ritik BangerDec 9, 2022

                In this example, the fetch function is added to the dependencies array for the useEffect hook. This means that the effect will be re-run any time the fetch function changes. However, since the fetch function is a built-in JavaScript function, it is not expected to change and this should not be a problem.

                It is generally a good idea to include all of the dependencies for an effect in the dependencies array, as this ensures that the effect will be run only when the dependencies change. In this case, adding the fetch function to the array will not cause any problems, and it will satisfy the linter.

                • Apoorva Gupta
                  Apoorva GuptaOct 25, 2023
                  const OnboardingInfoStack = () => {
                    const [imageDimensions, setImageDimensions] = React.useState<
                      Array<{ width: number; height: number }>
                    >([]);
                  
                    React.useEffect(() => {
                      const getImageDimensions = (imgSrc: string, index: number) => {
                        const image = new Image();
                        image.onload = () => {
                          const newDimensions = [...imageDimensions];
                          newDimensions[index] = { width: image.width, height: image.height };
                          setImageDimensions(newDimensions);
                        };
                        image.onerror = (error) => {
                          console.error(`Error loading image: ${imgSrc}`, error);
                        };
                        image.src = imgSrc;
                      };
                  
                      partnerImagePaths.forEach((path, index) => {
                        getImageDimensions(path, index);
                      });
                    }, []);```
                  
                  
                  
                  `374:6  warning  React Hook React.useEffect has a missing dependency: 'imageDimensions'. Either include it or remove the dependency array  `
                  
                  what to do in such case?
                  
                  1. 
                  
                  Enter fullscreen mode Exit fullscreen mode
                  • Clara Situma
                    Clara SitumaOct 27, 2023

                    add imageDimensions to dependency array

                    • Apoorva Gupta
                      Apoorva GuptaOct 27, 2023

                      infinite loop?

                      • Ritik Banger
                        Ritik BangerOct 30, 2023

                        Use useRef to create reference to your state and then use the ref inside your useEffect.

    • Clara Situma
      Clara SitumaDec 9, 2022

      Thanks for that addition Ritik :)

    • Henrique
      HenriqueJan 19, 2024

      What if I want my effect to be executed once when the component is mounted. For example, a simple static website that fetches some API and display some content. Is there still a problem?

      • Ritik Banger
        Ritik BangerJan 20, 2024

        This is fine. Create an async function with using useCallback hook that will call your API and then call that async function inside useEffect with no dependencies.

Add comment