关于 react 函数式组件的 更新问题?

问题复现

gg.gif

import { useState } from "react";
import { Table, Button } from "antd";

export default function Home(props) {
    console.log('render')

    const cols = [
        { title: 'id', dataIndex: 'id' },
        {
            title: '按钮',
            dataIndex: 'btn',
            render: () => <Button onClick={() => console.log('dataSource', dataSource)}>get dataSource</Button>
        },
    ]
    const [columns, setColumns] = useState([])
    const [dataSource, setDataSource] = useState([])
    return (
        <div>
            <Table columns={columns} dataSource={dataSource} rowKey="id" pagination={false} />
            <Button onClick={() => {
                setDataSource([{ id: 1 }])
                setColumns(cols)
            }}>
                setDataSource and setColumns
            </Button>
        </div>
    )
}

期望这里可以输出最新的 dataSource

7e2fd8b67a0b89c427e5bdb83b2abc9.png

我能感觉到是引用了上一轮渲染的 dataSource 才导致的为空,,但是怎么解决比较好呢?

我目前是又额外引入了 useRef , 每次 setDataSource 的时候手动把最新的 dataSource 存了一下,,但是感觉这么干不合理

阅读 3.6k
1 个回答

emmmm 这个坑你自己挖的。。你自己填吧。。。

首先你设置了dataSource,假设那些依赖都正确的情况下 在下一次render中 你的cols中每一个按钮的click事件会把最新的dataSource打印出来。

问题在哪里呢。。。问题在于 你设置完新的dataSource后。直接把这一次render中的cols赋值给了columns。然后下一次render中虽然cols改变了。但是不会同步更新到columns。然后antd的表格开心的拿着你上一次的cols作为columns去渲染。所以没打印出来最新的dataSource。。

知道原因解决这个问题应该很简单。直接把cols给antd的columns(我从代码里没看懂为啥要分开写。。我觉得直接用没毛病。),或者在cols变动后同步给columns。

补充cols变动同步方案

const cols = useMemo(() => [
        {title: 'id', dataIndex: 'id'},
        {
            title: '按钮',
            dataIndex: 'btn',
            render: () => <Button onClick={() => {
                console.log(dataSource)
            }}>get dataSource</Button>
        },
    ], [dataSource])
    useEffect(() => {
        setColumns(cols)
    }, [cols])

还有看了一下数据依赖关系。。。dataSource也不是这么取的呀。。antd表格的render函数中已经有了当前的dateSource值了

{
            title: '按钮',
            dataIndex: 'btn',
            render: (v, allData) => <Button onClick={() => {
                console.log(allData)
            }}>get dataSource</Button>
        }
推荐问题
宣传栏