1

My question is regarding including an array that doesn't stop loading even when using useEffect. Other questions do not cover this topic; they cover similar but different approaches.

I am fetching data from my firebasefirestore and setting the data required.

Now I only need the data to run once and to be displayed, but when i use the useEffect hook with the dependency (it doesn't work without the dependency), it starts running continuously and i can see in the network tab that it keeps on fetching the data non stop.

How can I fix this, what can i do to make my useEffect run only once even if it has a dependency array.

Here is my code:

import React, { Component, useEffect, useState, useCallback } from "react";
  const [agentData, setAgentData] = useState([]);
  const [agentID, setAgentID] = useState("");

  const getSalesAgentInformation = async () => {
    await firebase
      .firestore()
      .collection("Employees")
      .where("employeeID", "==", agentID)
      .get()
      .then((snapshot) => {
        const salesAgent = snapshot.docs.map((doc) => doc.data());
        setAgentData(salesAgent);
      });
  };
  useEffect(() => {
    getSalesAgentInformation();
  }, [agentData]);
motionless570
  • 925
  • 1
  • 10
  • 26
  • If you only want it to run ONCE regardless of whether `agentData` changes or not (which seems like what you want), use an EMPTY ARRAY as the dependency array – Bao Huynh Lam May 22 '22 at 22:55
  • @BaoHuynhLam I already know that... i want the dependency array as without it the information will not be displayed... – motionless570 May 22 '22 at 23:11

1 Answers1

2

From the release notes for React v18:

In the future, we’d like to add a feature that allows React to add and remove sections of the UI while preserving state. For example, when a user tabs away from a screen and back, React should be able to immediately show the previous screen. To do this, React would unmount and remount trees using the same component state as before.

This feature will give React apps better performance out-of-the-box, but requires components to be resilient to effects being mounted and destroyed multiple times. Most effects will work without any changes, but some effects assume they are only mounted or destroyed once.

The right way to do this is to keep track of whether or not it’s the first render and use that as a condition for executing your code in the effect. This way, it doesn't matter whether there are zero, one, or many dependencies for the effect. Here's an example which uses a custom hook to track that state:

TS Playground

import {useEffect, useRef} from 'react';

function useIsFirstRender () {
  const ref = useRef(true);
  if (ref.current) {
    ref.current = false;
    return true;
  }
  return false;
}

function Component () {
  const isFirstRender = useIsFirstRender();

  useEffect(() => {
    // If it's not the first render, return early from the function
    if (!isFirstRender) return;
    // else, do other things...
    console.log('First render');
  });

  return null;
}

jsejcksn
  • 27,667
  • 4
  • 38
  • 62
  • TypeScript? but i am using reactjs which is javascript – motionless570 May 22 '22 at 23:12
  • Can youg ive me a solution for my specific problem? – motionless570 May 22 '22 at 23:12
  • @Derek I removed the one type annotation. Now it's JavaScript. – jsejcksn May 22 '22 at 23:17
  • A [terser version](https://www.typescriptlang.org/play?noUncheckedIndexedAccess=true&target=99&useUnknownInCatchVariables=true&exactOptionalPropertyTypes=true&ssl=3&ssc=29&pln=3&pc=38#code/JYWwDg9gTgLgBAbwK4GcCmAlNAzAvnbKCEOAcijQEMBjGUgbgFgAoF7JAO1uAg7lTQBJFADFgUFDCwcAJmihwAFAEoAXHABGECABsqfBCzhxqvSXArY4AXn7os2RTChI0yps2MUYSKH0sAdNS+FBzwAPxwAISKgcFQofC22JQ66Mpw6ilpaB64LEA) of the hook. – jsejcksn May 22 '22 at 23:26
  • this is some what correct, but now it just doesn’t display any data at all even if include the dependency array. why is that? – motionless570 May 23 '22 at 08:40
  • @Derek I'm not sure what you mean — there is only a `console.log` statement in the effect in my answer. Stack Overflow is Question-Answer format, and is not designed for conversational debugging. [Does this answer the question that you asked?](https://stackoverflow.com/help/someone-answers). If you have a question about code that you have not yet shown, you are welcome to [ask a new question](https://stackoverflow.com/questions/ask) — if you do, be sure to include a [minimal, reproducible example](https://stackoverflow.com/help/minimal-reproducible-example). – jsejcksn May 23 '22 at 22:57