【问题标题】:useCallback and React.memo accessing stateuseCallback 和 React.memo 访问状态
【发布时间】:2020-11-05 15:47:50
【问题描述】:

我有一个功能组件板,在返回的 JSX 中,我遍历一个 2D 数组并打印一堆 Squares,然后我将一个处理程序和一些额外的信息传递给它们中的每一个。如果 Square 接收到相同的道具,我想阻止它们重新渲染,因此 Square 组件在 React.memo() 方法中。在我处理板更新的板组件中,我使用 useCallback 处理程序,因此在重新渲染期间我不会传递全新的函数。

我没有得到的是,在 clickHandler 的主体中,我始终可以访问调用到板的新更新的 2D 数组,但我从未收到更改的播放器,它始终保持在 1。然而,状态本身切换为 2,反之亦然。如果我将播放器作为依赖项传递,我的所有 300 多个方块都会重新渲染。

我没有将状态作为道具传递给 Square,我只是在棋盘上映射并从棋盘本身传递值。

所以我的问题是,为什么我可以访问 clickHandler 中的更新板,但不能访问播放器。当我点击我的一个方块时,它总是被 player1 占用,这是默认设置。

链接到整个仓库(它只是几个组件):https://github.com/TreblaCodes/react-connect5

谢谢

    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
    },[])

【问题讨论】:

    标签: javascript reactjs callback frontend memoization


    【解决方案1】:

    尝试将玩家和棋盘传递给 useCallback 的第二个参数。然后,每当玩家或棋盘发生变化时,您都会获得新的回调实例。

    像这样:

    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])
    

    【讨论】:

    • 然后强制我所有的 Squares 重新渲染...没有依赖关系,clickHandler 中的板是更新版本,而不是播放器
    • 你的板子更新的原因是你打破了不变性原则。这一行“board_copy[y][x] = player;”修改原始对象。
    • 让 board_copy = [...board],应该复制一份
    • @Albert.Hadacek 它不是深拷贝。每个条目都引用同一个对象。所以,board_copy[y] === board[y]
    猜你喜欢
    • 1970-01-01
    • 2020-11-05
    • 1970-01-01
    • 2021-10-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多