State seems to be reverting back to its initial state after useeffect is run

166 views Asked by At

I am having an issue where it seems a state is reverting to its initial state without being prompted to. The state is change in a function, which then triggers a useeffect. The useffect then runs, recognizing and console.logging the update state. Then however, the next call to the function says the state is still in its initial state. My code is below, unfortunately I cant include a full snippet as it includes some things that cannot be shared/run.

Here is where I declare my states:

const [playerTeam, setPlayerTeam] = useState({});
const [movement, setMovement] = useState({ active: false, character: null });

Here is my useeffect:

  useEffect(() => {
    const canvas = canvasReference.current;
    const context = canvas.getContext("2d");
    console.log("drawing", movement);

    setCharacterUpdate(false);

    mapImage.onload = () => {
      canvas.width = mapImage.width;
      canvas.height = mapImage.height;
      context.drawImage(mapImage, 0, 0);
      for (const [key, value] of Object.entries(playerTeam)) {
        context.drawImage(
          playerTeam[key].spriteImg,
          playerTeam[key].x,
          playerTeam[key].y
        );
      }
    };
  }, [playerTeam, movement]);

Here is where I change states that I expect to trigger the useeffect:

function handleClick(canvas, e) {
    console.log(movement);
    //get the coordinates of the user's curson on click
    let rect = canvas.getBoundingClientRect();
    let x = e.clientX - rect.left;
    let y = e.clientY - rect.top;

    //movement mode is active (last click was a click on an ally character)
    if (movement.active) {
      moveCharacter(x, y);
    }
    //if we arent in movement mode...
    else {
      //cycle through player's team
      for (const [key, value] of Object.entries(playerTeam)) {
        //if the coordinates of the click are on the same 48 x 48 tile as one of the ally characters
        if (
          x >= playerTeam[key].x &&
          x <= playerTeam[key].x + 47 &&
          y >= playerTeam[key].y &&
          y <= playerTeam[key].y + 47
        ) {
          console.log("Batman!");

          const enterMovement = {
            active: true,
            character: playerTeam[key].name,
          };

          //put us in movement mode
          setMovement(enterMovement);

          break;
        }
      }
    }
  }

  //function for moving the character
  function moveCharacter(x, y) {
    console.log("here");
    let newTeam = playerTeam;
    newTeam[movement.character].x = x - (x % 48);
    newTeam[movement.character].y = y - (y % 48);
    setPlayerTeam(newTeam);
    let exitMovement = { active: false, character: null };
    setMovement(exitMovement);
    console.log(movement, playerTeam["batman"]);
  }

Here are some things I noticed that confuse me:

  • The handleClick function never reads movement.active as true. The console log at the beginning of handle click shows it is false on every call to the function.

  • The useeffect function, however, has a console log in it that shows that the movement field is, in fact, being changed to true. The useeffect runs on each click, indicating that the movement field is in fact changing, but somehow between the useffect triggering and the next click, the movement.active field is reverting back to its initial state.

*The playerTeam state is not empty by the way, it is populated in a separate section of code.

Thanks for any ideas/answers!

0

There are 0 answers