简体   繁体   English

useCallback 和 React.memo 访问状态

[英]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.我有一个功能组件板,在返回的 JSX 中,我遍历一个 2D 数组并打印一堆 Squares,然后将一个处理程序和一些附加信息传递给它们中的每一个。 I wanted to prevent them from rerendering if the Square receives the same props so the Square component is within the React.memo() method.如果 Square 收到相同的 props,我想防止它们重新渲染,因此 Square 组件位于 React.memo() 方法中。 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.在我处理板子更新的板子组件中,我有一个带有 useCallback 的处理程序,所以我不会在重新渲染期间传递一个全新的函数。

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.我不明白的是,在 clickHandler 的主体中,我始终可以访问称为板的最新更新的 2D 数组,但我从未收到更改过的玩家,它始终保持为 1。然而,状态本身被切换为2 反之亦然。 If I pass player as the dependency, all of my 300+ squares are obvs rerendered.如果我将 player 作为依赖项传递,则所有 300 多个方块都将重新渲染。

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.我没有将状态作为道具传递给 Square,我只是在板上映射并从板本身传递值。

So my question is, why I have access to the updated board in the clickHandler, but not the player.所以我的问题是,为什么我可以访问 clickHandler 中的更新板,但不能访问播放器。 As when I click one of my squares it gets always taken by player1 which is the default.当我点击我的一个方块时,它总是被 player1 占用,这是默认值。

Link to the whole repo (it is just few components) : https://github.com/TreblaCodes/react-connect5链接到整个 repo(它只是几个组件): 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.只需尝试将 player 和 board 传递给 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])

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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