antd中嵌套表格,子表格数据相同的问题解决(hook写法)
相信很多朋友在使用antd的嵌套表格的时候都碰到了这个问题,本人也深有体会,简直愁的不行,不过在经过和百度的一番争斗之后,终于是找到的问题的原因所在。
首先,antd的表格数据源dataSource接收的是一个数组,如果我们子表格每次接收的数组都是一个单独的新的数组,那么就会造成所有的子表格都是一样的,因为每次展开只渲染了这一个数组
那么我们就要把每次请求到的子表格数据给存起来了,这里我用的是对象键值对的方式去存储的
因为没有后台数据,所以我这边就先模拟了一些数据
const ChildrenDataOne = [ { name: 'XiaoHua1', age: 15, address: 'ZhengZhou', key: 0 }, { name: 'XiaoHua2', age: 15, address: 'ZhengZhou', key: 1 }, { name: 'XiaoHua3', age: 15, address: 'ZhengZhou', key: 2 }, ] const ChildrenDataTwo = [ { name: 'XiaoBai1', age: 15, address: 'ZhengZhou', key: 0 }, { name: 'XiaoBai2', age: 15, address: 'ZhengZhou', key: 1 }, { name: 'XiaoBai3', age: 15, address: 'ZhengZhou', key: 2 }, ] const ChildrenDataThree = [ { name: 'XiaoHei1', age: 15, address: 'ZhengZhou', key: 0 }, { name: 'XiaoHei2', age: 15, address: 'ZhengZhou', key: 1 }, { name: 'XiaoHei3', age: 15, address: 'ZhengZhou', key: 2 }, ] const ChildrenDataFour = [ { name: 'XiaoLan1', age: 15, address: 'ZhengZhou', key: 0 }, { name: 'XiaoLan2', age: 15, address: 'ZhengZhou', key: 1 }, { name: 'XiaoLan3', age: 15, address: 'ZhengZhou', key: 2 }, ]
这个方法每次点击展开按钮时会把相对应的数据存入到 data 这个对象中,大概效果是 { 1: [ 数据 ], 3: [ 数据 ], 2: [ 数据 ] }
1 const openClick = (status, item) => { // status(子表格展开的状态) item(当前项) 2 if (!status) return 3 // 判断 如果子表格收起时 直接退出当前函数,不进行请求存储 4 if (item.Cid === 1) { 5 setData({ ...data, [item.Cid]: ChildrenDataOne }) 6 } 7 if (item.Cid === 2) { 8 setData({ ...data, [item.Cid]: ChildrenDataTwo }) 9 } 10 if (item.Cid === 3) { 11 setData({ ...data, [item.Cid]: ChildrenDataThree }) 12 } 13 if (item.Cid === 4) { 14 setData({ ...data, [item.Cid]: ChildrenDataFour }) 15 } 16 }
好,现在我们有了所有展开的数据,但是因为存储到对象里面,所以我们还需要一个 唯一值(id)每次取匹配我们存储到对象里面的数据
这个方法是渲染子表格用的,它第一个参数是所有展开的对应的数据,我们就可以从这些数据中取到唯一值(id)
可能有小伙伴疑问了为什么要从这里取,因为它第一个参数输出的是(所有展开的数据),也就是说我们可以拿到所有已展开的id,然后将对应的数据给放进去
我这边也是踩过坑的,我每次展开的时候存了一个id,然后就导致了我虽然有每个展开的数据,但是没有每个展开的id,就造成了都是一样的数据
const expandedRowRender = (item) => { return ( <Table columns={ChildrenColumns} pagination={false} dataSource={data[item.Cid]} /> ) }
这里是全部的代码,这边是没有使用 redux或者dva,仅仅是使用state在页面上模拟了一下,不过思路是正确的,小伙伴们把思路看懂了,然后搬到redux/dva里面就可以了
import React, { useState } from 'react' import { Table } from 'antd' import { ParentData, ParentColumns, ChildrenColumns, ChildrenDataOne, ChildrenDataTwo, ChildrenDataThree, ChildrenDataFour, } from './Sourse' import './styles.less' export default function App() { const [data, setData] = useState(null) const expandedRowRender = (item) => { return (
// 子表格 <Table columns={ChildrenColumns} pagination={false} dataSource={data[item.Cid]} /> ) } const openClick = (status, item) => { if (!status) return if (item.Cid === 1) { setData({ ...data, [item.Cid]: ChildrenDataOne }) } if (item.Cid === 2) { setData({ ...data, [item.Cid]: ChildrenDataTwo }) } if (item.Cid === 3) { setData({ ...data, [item.Cid]: ChildrenDataThree }) } if (item.Cid === 4) { setData({ ...data, [item.Cid]: ChildrenDataFour }) } } return ( <div className="pages-app">
// 父表格 <Table className="components-table-demo-nested" columns={ParentColumns} expandable={{ expandedRowRender }} // 渲染子表格的回调 dataSource={ParentData} onExpand={openClick} // 展开时触发的回调 /> </div> ) }