Home > database >  React Hooks Issue with state getting reset
React Hooks Issue with state getting reset

Time:10-18

I my trying to develop Tic Tac Toe game using React and am stuck at the basic step i.e. I want the first move to be X and flip the next one to O and so-on.

I have the below code. So, I try to initialize state "data" (what is to be set) initially to X and then set the state "nextChoice" to be the reverse via;

nxtChoice = (data === "X") ? "O" : "X";
setNextChoice(nxtChoice);

Now, it seems like the issue is that the Square component gets re-mounted again and then the "firstMove" state gets set to true every time causing the issue i.e. not able to flip between X and O.

Could you please help me understand what the logical issue is with above code and how can I not reset firstMove every time ?

function Square(props) {
  const [firstMove, setFirstMove] = useState(true);
  let [nextChoice, setNextChoice] = React.useState("X");
  let [data, setData] = React.useState("");

  useEffect(() => {
    if (data !== "") {
      nxtChoice = (data === "X") ? "O" : "X";
      setNextChoice(nxtChoice);
    }
  }, [data]);

  const squareClicked = () => {
    let nxtChoice = firstMove ? "X" : nextChoice;
    setData(nxtChoice);
    setFirstMove(false);
  };

  return (
    <div className="square" style={squareStyle} onClick={squareClicked}>
      {data}
    </div>
  );
}

class Board extends React.Component {
  render() {
    return (
      <div style={containerStyle} className="gameBoard">
        <div id="statusArea" className="status" style={instructionsStyle}>
          Next player: <span>X</span>
        </div>
        <div id="winnerArea" className="winner" style={instructionsStyle}>
          Winner: <span>None</span>
        </div>
        <button style={buttonStyle}>Reset</button>
        <div style={boardStyle}>
          <div className="board-row" style={rowStyle}>
            <Square row={"1"} column={"1"} />
            <Square row={"1"} column={"2"} />
            <Square row={"1"} column={"3"} />
          </div>
          <div className="board-row" style={rowStyle}>
            <Square row={"2"} column={"1"} />
            <Square row={"2"} column={"2"} />
            <Square row={"2"} column={"3"} />
          </div>
          <div className="board-row" style={rowStyle}>
            <Square row={"3"} column={"1"} />
            <Square row={"3"} column={"2"} />
            <Square row={"3"} column={"3"} />
          </div>
        </div>
      </div>
    );
  }
}

Code can also be seen on https://codesandbox.io/s/rough-glade-c1ssw?file=/src/App.js:1307-3349

CodePudding user response:

What you see happening is not the Square component is remounted, but for every instance of Square, it has a separate individually working state.

In order for the game to work those states should be moved to the Board component and passed to each of the Square components.

CodePudding user response:

There are so many problems...

The main one being that the state of the game is stored within the squares instead of within the app component.

  • Related