react firebase store infinite loop

Viewed 137

I am trying to implement a firebase store database into my react app.

Once you click on the challenge button, it saves it to the database and then it should print on the dashboard. Right now it gets into an infinite loop and I cannot really figure out why. Could anyone please help? Also, how to setChall and setco2 outside of .then so it can be used in the return of the component?

Below part of the code from the dashboard:

  const [challs, setChall] = useState([]);
  const [co2, setco2] = useState(0);

  const handleChall = (e) => setChall(e);
  let getMe = (e) => (getMe = e);
  const handleCo2 = (e) => {
    setco2(co2 + e);
  };

  database
    .collection("Dashboard")
    .get()
    .then((querySnapshot) => {
      querySnapshot.forEach(function (doc) {
        const challenge = doc.data().chall;
        const takenco2 = doc.data().Co2Consumption;
        console.log(challenge);
        getMe(challenge);
        handleCo2(takenco2); //causes an infinite loop
      });
      handleChall(getMe);
      console.log(challs);
    })
    .catch(function (error) {
      console.log("Error getting documents: ", error);
    });

Here is a ChooseChellenge.js class

function Challange() {
  const [isPopped, setPop] = useState(false);

  const plsWork = (e) =>{
    setPop(!isPopped);
    const theOne = challs[e];
    console.log(theOne);
    addToFire(theOne);
  }

  const [challs, setChalls] = useState([]);

  useEffect(() => {
    const fetchData = async () => {
      var challs = [];
      await database
        .collection("Challenges")
        .get()
        .then((snapshot) => {
          snapshot.docs.forEach((doc) => {
            challs.push(doc.data().ChallengeName);
          });
        });
      setChalls(challs);
    };
    fetchData();
  }, []);

   const addToFire = (addThatCh) => {
    const buttonChall = addThatCh;
    //take that from db if possible
    const co2c = 20;
    database
      .collection("Dashboard")
      .add({
        chall: buttonChall,
        Co2Consumption: co2c,
      })
      .then((newDocument) => {
        //how to change the ID to not have an automatic id
        console.log("New document created with ID: ", newDocument.id);
      })
      .catch((error) => {
        console.error(error.message);
      });
  }; 
//user with collection of challanges!!! the ID needs to be the name of the challenge! co2 is inside
  

  return (
    <>
      {isPopped && <Dialog2 />}
      <div className="challanges">
        <h1 className="newchallenge">Choose New Challange</h1>
        <button className="challangeBtn" onClick={() => plsWork(0)} >
          {challs[0]} (31days)
        </button>
        <button className="challangeBtn" onClick={() => plsWork(1)} >
          {challs[1]} (14days)
        </button>
        <button className="challangeBtn" onClick={() => plsWork(2)} >
          {challs[2]} (31days)
        </button>
        <button className="challangeBtn" onClick={() => plsWork(3)} >
          {challs[3]} (31days)
        </button>
        <button className="challangeBtn" onClick={() => plsWork(4)} >
          {challs[4]} (365days)
        </button>
      </div>
    </>
  );
}

export default Challange;

1 Answers

This part

database
.collection("Dashboard")
.get()
...

is directly in the dashboard, so it runs everytime the dashboard renders, modify the state, provoke a render, and so on. Place it into a useEffect will correct some bugs, maybe not the one your looking for but it's a first step to take.

Related