简体   繁体   中英

useCallback and React.memo accessing state

I have a functional component Board and within the return JSX I go over a 2D array and print bunch of Squares and I pass a handler plus some additional info into each of them. I wanted to prevent them from rerendering if the Square receives the same props so the Square component is within the React.memo() method. In the Board component where I handle the updates of the board I have the handler with useCallback so I don't pass a brand new function during rerenders.

What I don't get is that in the body of the clickHandler I have access always to the fresh updated 2D array called to board, yet I never receive the changed player, it always stays at 1. Yet, the state itself is toggled to 2 and vice versa. If I pass player as the dependency, all of my 300+ squares are obvs rerendered.

I am not passing the state as a prop to the Square, I just map over the board and pass values from the board itself.

So my question is, why I have access to the updated board in the clickHandler, but not the player. As when I click one of my squares it gets always taken by player1 which is the default.

Link to the whole repo (it is just few components) : https://github.com/TreblaCodes/react-connect5

Thanks

    const [player, setPlayer] = useContext(PlayerContext)
    const [board, setBoard] = useContext(PositionsContext)

    const clickHandler = useCallback((x,y) => {
        let board_copy = [...board]
        board_copy[y][x] = player;
        setBoard(board_copy) 
        console.log(board) //updated
        setPlayer(player === 1 ? 2 : 1)
        console.log(player) // stays at 1
    },[])

Just try to pass player and board into the second parameter of useCallback. Then whenever player or board gets changed you'll get new instance of callback.

Like this:

const [player, setPlayer] = useContext(PlayerContext)
const [board, setBoard] = useContext(PositionsContext)

const clickHandler = useCallback((x,y) => {
    let board_copy = [...board]
    board_copy[y][x] = player;
    setBoard(board_copy) 
    console.log(board) //updated
    setPlayer(player === 1 ? 2 : 1)
    console.log(player) // stays at 1
},[player, board])

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM