1

I'm trying to update the game data but it comes from behind. I think I should call this.setState({}) in a different sort of way, but can anybody help me doing it?

Here's the code:

    handleMove(cords) {
        // Return if the game is already over
        if (this.state.winner) {
            return
        }

        // This should be the copy of the this.state.history till the end
        const history = this.state.history.slice();
        const current = history[history.length - 1];

        // Cords parameter is an array of coordinates of squares whose values are
        //to be changed or passed in
        const color = this.state.blackIsNext ? "black" : "white";
        // Here, I create a new squares array, states of each squares
        //one-by-one are added, which will be immutably pushed inside the new history
        //array
        const nextSquares = current.squares.map((row, y) =>
            row.map((square, x) =>
                // find if this [x,y] is in the cords array and replace it if it is
                cords.some((cord) => cord[0] === y && cord[1] === x) ? color : square
            )
        );
        
        // Create the new history element, element's state.history
        //value will be this new one
        const newHist = history.concat({squares: nextSquares})
        this.setState({
            history: newHist,
            stepNumber: history.length,
        });
        

If this code is not enough to give you a hint, then please do let me know. Thanks a lot in advance.

Efe FRK
  • 177
  • 1
  • 13
  • 1
    Whaat do you mean by it comes from behind – Shubham Khatri Apr 14 '21 at 06:11
  • try this `this.setState({ history: ...newHist, stepNumber: newHist.length});` – Nguyễn Văn Phong Apr 14 '21 at 06:12
  • Please do clarify what you mean by "comes from behind". How or what are you doing to validate that state updates are a render cycle delayed? I suspect a possible duplicate of https://stackoverflow.com/questions/41446560/react-setstate-not-updating-state – Drew Reese Apr 14 '21 at 06:16
  • it does not contain the last state of the game board that I'm working on; I'm trying to develop an Othello game and history is an array where all the game board possessions are stored from the opening till the end – Efe FRK Apr 14 '21 at 06:25
  • `this.handleMove(anArrayOfMoves)` and then `console.log(this.state.history)`, right after I call the function. They're called when my game board is clicked on – Efe FRK Apr 14 '21 at 06:30
  • Can you share (***in your question***) where you are detecting that you don't have the current state? In other words, show us what you are doing? My intuition is this is a duplicate of the post I linked previously, but looking for confirmation it may be something else. – Drew Reese Apr 14 '21 at 06:36
  • I added some comments that does explain the code I've written. I hope it'll be helpful – Efe FRK Apr 14 '21 at 07:52
  • You said "`this.handleMove(anArrayOfMoves)` and then `console.log(this.state.history)`, right after I call the function." I can assume these are both called in a single function but I rather verify than make assumptions. – Drew Reese Apr 14 '21 at 07:54

1 Answers1

0

It took a couple of days to solve it but finally done. I called a portion of the code, that originally comes after I call setState, inside the setState callback. Like this:

handleMove(cords) {
        // You'll return if the game is already over or the value of the square is NOT null
        if (this.state.winner) {
            return
        }
        // Handle the recently made move here
        const history = [...this.state.history];
        const squares = history[history.length - 1].slice();
        // Handle click
        const color = this.state.blackIsNext ? "black" : "white";
        const nextSquares = squares.map((row, y) =>
            row.map((square, x) =>
                cords.some((cord) => cord[0] === y && cord[1] === x) ? color : square
            )
        );
        //console.log(this.state.history)
        const newHist = history.concat([nextSquares])
        return newHist
    }

And then:

const upcoming = this.handleMove(turning)
this.setState({
    history: upcoming,
    stepNumber: upcoming.length - 1
},() => {
    // My function that is affected by setState
    this.setWinnerAndTurn(this.state.history)
    console.log(this.state.history)
})

After all my researches, from calling setState synchronously to setTimeOut(), I believe that this is (by far) the easiest way to handle setState update.

Efe FRK
  • 177
  • 1
  • 13