Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Avoid infinite loop when updating

I have to update a state of items and see the changes right away. When I’m doing this below, I get an infinite loop.

 useEffect(() => {
    const playersInFight = gameData.characters.filter((x) =>
      fightData.currentPositionInfoDTOS.some((y) => y.entityId == x.id)
    );

    let orderedCharacters = addPlayers(
      playersInFight,
      fightData.currentPositionInfoDTOS,
      fightData.turnOrder
    );
    setAllCharacterCards(orderedCharacters);

  }, [fightData, gameData, fightInfo, allCharacterCards, allCharacters]);

I have tried also like this:

  useEffect(() => {
    const playersInFight = gameData.characters.filter((x) =>
      fightData.currentPositionInfoDTOS.some((y) => y.entityId == x.id)
    );

    let orderedCharacters = addPlayers(
      playersInFight,
      fightData.currentPositionInfoDTOS,
      fightData.turnOrder
    );
    setAllCharacterCards(orderedCharacters);

  }, [fightData, gameData, fightInfo, allCharacterCards, allCharacters]);

  useEffect(() => {
    setAllCharacterCards(allCharacterCards);
  }, [allCharacterCards]);

And thanks to that I don’t have an infinite loop, but to see the changes I have to refresh the page…
How can I solve this?

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

Update:
Here is my return:

return (
    <section>
        <div className="player-fight">
          {allCharacterCards ? (
            <div>
              {allCharacterCards.map((c, idx) => {
                return (
                  <li key={idx} className="player-fight-bottom__player-card">
                    <CardComponentPlayerCard
                      id={c.id}
                      name={c.name}
                      money={c.money}
                      health={c.health}
                      maxHealth={c.maxHealth}
                      mine={false}
                      description={c.description}
                      statuses={c.statuses}
                      image={c.photoPath}
                    />
                  </li>
                );
              })}
            </div>
          ) : (
            <LoadingSpinner />
          )}
        </div>
    </section>
  );

>Solution :

To avoid infinite looping you need to remove allCharacterCards from useEffect dependency array.

 useEffect(() => {
    const playersInFight = gameData.characters.filter((x) =>
      fightData.currentPositionInfoDTOS.some((y) => y.entityId == x.id)
    );

    let orderedCharacters = addPlayers(
      playersInFight,
      fightData.currentPositionInfoDTOS,
      fightData.turnOrder
    );

    setAllCharacterCards([...orderedCharacters]);

  }, [fightData, gameData, fightInfo, allCharacters]);

Explanation (after question edited)

    setAllCharacterCards([...orderedCharacters]);

This should fix your problem.

Since allCharacterCards is an array of objects you need to use spread operator ... to let react know that you are updating state everytime with new values.
Read more about – Deep copy vs shallow copy.

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading