Ant Design - Collapse expanded rows on click of pagination buttons - reactjs

I am implementing the expandable row feature on an ant design table (Expandable Row), and it works perfectly fine as stated on the ant design site. But I would like to expand the functionality of the table to include collapsing of the rows when the user clicks on the buttons to the lower right of the table that allow pagination. This is a fairly straightforward question so I won't clutter it by posting code. Any help or links would be greatly appreciated.
EDIT Code snippet
import * as React from 'react';
import { Tooltip, Table } from 'antd';
import * as IAssignmentsResponse from '../../interfaces/QC/IAssignmentResponse';
import * as moment from 'moment';
const expandedRowRender = (rowData) => {
const columns = [
{ title: 'Row1', dataIndex: 'Row1DataIndex', key: '1'},
{ title: 'Row2', dataIndex: 'Row2DataIndex', key: '2'},
{ title: 'Row3', dataIndex: 'Row3DataIndex', key: '3'},
];
return <Table
columns={columns}
dataSource={rowData.DataArray}
pagination={false}>
</Table>
}
const bindRows = (row) => {
return row.Workitem.WorkflowRefID;
}
const columns = [
{
title: 'MasterRow1',
dataIndex: 'MasterRow1DataIndex',
key: '1',
render(value) { return value.WorkflowRefID; },
onFilter: (value, record) => record.Workitem.data1.indexOf(value) === 0,
sorter: (a, b) => a.Workitem.data1 - b.Workitem.data1
},
{
title: 'MasterRow2',
dataIndex: 'MasterRow1DataIndex',
key: '2',
render(value, record) { return <Tooltip title={record.data2} mouseEnterDelay={.5}>{value}</Tooltip> },
onFilter: (value, record) => record.data2.indexOf(value) === 0,
sorter: (a, b) => a.data2- b.data2
},
{
title: 'MasterRow3',
dataIndex: 'MasterRow1DataIndex',
key: '3',
render(value, record) { return <Tooltip title={record.data3} mouseEnterDelay={.5}>{value}</Tooltip> },
onFilter: (value, record) => record.data3.indexOf(value) === 0,
sorter: (a, b) => a.data3- b.data3
}
]
return <Table rowKey={record => bindRows(record)}
columns={columns}
dataSource={this.props.assignmentData.AssignmentsResponse.Assignment}
expandedRowRender={record => expandedRowRender(record)}
onExpand={this.onTableRowExpand}
/>

You can achieve this using the expandedRowKeys method of the Ant Design's Table component's API, which is the list of keys of already expanded rows. An empty list means all rows are collapsed.
You can capture pagination button clicks using the onChange method, which can be used to call a function that sets the state of your component:
class MyTable extends Component {
constructor(props) {
super(props);
this.state = { currentPage: 1, expandedRows: [] };
this.handleChange = this.handleChange.bind(this);
}
handleChange(pagination) {
// changes the page, collapses all rows
this.setState({ currentPage: pagination.current, expandedRows: [] });
}
handleRowExpand(record) {
// if a row is expanded, collapses it, otherwise expands it
this.setState(prevState =>
prevState.expandedRows.includes(record.key)
? {
expandedRows: prevState.expandedRows.filter(
key => key !== record.key
)
}
: { expandedRows: [...prevState.expandedRows, record.key] }
);
}
render() {
return (
<Table
dataSource={YOUR_DATA}
...OTHER_PROPS
pagination={{ current: this.state.currentPage }}
// pagination buttons clicked
onChange={this.handleChange}
// expand + icon clicked
onExpand={(expanded, record) => this.handleRowExpand(record)}
// tell the 'Table' component which rows are expanded
expandedRowKeys={this.state.expandedRows}
/>
);
}
}

Related

Edit custom column component while adding new row of Material Table

With the React Material Table library, is it possible to render a custom component while adding a new row? I'm using a custom component (a Material UI select box, actually), for the Expected Result column. When I add a new row, I only see a field for the Requirement column, not the Expected Result column. Is it possible to add an input for the Expected Result column of the new row as well?
Another option is to not use custom components at all and instead use something like the Cell Editable Example of https://material-table.com/#/docs/features/editable. However, I'm not a fan of the extra clicks that it takes to edit the Expected Result, compared to directly using a Select field.
import MaterialTable from 'material-table'
import { MenuItem, Select } from '#material-ui/core'
import React, { useState } from 'react'
import update from 'immutability-helper'
type PassFailNA = 'Pass' | 'Fail' | 'N/A'
type RowData = {
requirementId: number,
requirementName: string,
expectedResult: PassFailNA,
expectedResultId?: number
}
export function ExpectedResultsTable(props: {
scenarioId: number
}) {
const [tableData, setTableData] = useState<RowData[]>([{ requirementId: 1, requirementName: 'hello', expectedResult: 'Pass' }])
const { enqueueSnackbar } = useSnackbar()
const handleSelect = (id: number) => (event: React.ChangeEvent<{ name?: string; value: any }>) => {
setTableData((tableData: RowData[]) => {
const rowNum = tableData.findIndex(x => x.requirementId === id)
return update<RowData[]>(tableData, {
[rowNum]: { expectedResult: { $set: event.target.value } }
})
})
}
return (
<MaterialTable<RowData>
title=""
columns={[
{
title: 'Requirement',
field: 'requirementName'
},
{
title: 'Expected Result',
field: 'expectedResult',
render: (rowData) => (
<Select value={rowData.expectedResult} onChange={handleSelect(rowData.requirementId)}>
<MenuItem value="Pass">Pass</MenuItem>
<MenuItem value="Fail">Fail</MenuItem>
<MenuItem value="N/A">N/A</MenuItem>
</Select>
)
}
]}
data={tableData}
editable={{
onRowAdd: newRow =>
new Promise((resolve, reject) => {
setTimeout(() => {
setTableData(tableData => update(tableData, { $push: [{ ...newRow, expectedResult: 'N/A'}] }))
resolve()
}, 1000)
})
}}
/>
)
}
To achieve what you are looking for, I think you should specify the editComponent property ( besides render ) when defining the column. That prop takes a function where you can define the component used during the edit or creation phase.
Here is an example I made with a boolean input:
const tableColumns = [
{ title: "Client", field: "id" },
{ title: "Name", field: "name" },
{
title: "booleanValue",
field: "booleanValue",
editComponent: (props) => {
console.log(props);
return (
<input
type="checkbox"
checked={props.value}
onChange={(e) => props.onChange(e.target.checked)}
/>
);
},
render: (rowdata) => (
<input type="checkbox" checked={rowdata.booleanValue} />
)
}
];
Link to working sandbox. I hope that works for you!

MobX ReactJS AntD updates won't re-render

So I'm trying change some table data within my AntD Table using ReactJS and MobX. The data in my MobX observable changes, but the table doesn't re-render an update until I say.... resize the page and the table re-renders. I've recreated my issue on CodeSandbox - it's not the exact data type, but this is the EXACT issue I'm running into, any thoughts???
https://codesandbox.io/s/remove-items-from-mobx-array-forked-3nybr?file=/index.js
#action
change = (key) => {
this.data
.filter(item => key === item.key)
.forEach(piece => {
piece.key = 10;
});
console.log(this.data);
};
const FooTable = () => {
const columns = [
{
title: "ID",
dataIndex: "key"
},
{
title: "Name",
dataIndex: "name"
},
{
title: "Last Name",
dataIndex: "lastName"
},
{
title: "Actions",
render: (text, record) => {
return (
<Button
type="link"
icon="delete"
onClick={() => tableStore.change(record.key)}
>
Delete
</Button>
);
}
}
];
return useObserver(() => {
return <Table columns={columns} dataSource={tableStore.data} />;
});
};
Because AntD Table is not observer by itself you need to use toJS on your data before you pass it to AntD.
import { toJS } from "mobx";
// ...
const FooTable = () => {
const columns = [ ... ];
return useObserver(() => {
return <Table columns={columns} dataSource={toJS(tableStore.data)} />;
});
};

How do you use popconfirm in an antd react table?

I have a reactjs component which displays an antd table of which one of the columns is to execute an action to archive the item in the row. If someone clicks on Archive I want it to show a popconfirm with yes/no confirmation before it moves forward and archives the item.
Everything works fine until I add the Popconfirm block. Then I get the below error. I think that there is something wrong with my usage of onconfirm and oncancel in the popconfirm but i'm just not getting something probably obvious here. Appreciate any feedback!
import React, { Component } from 'react';
import { connect } from 'react-redux';
import selectProperties from '../selectors/properties';
import { Table, Tag, Divider, Popconfirm, message } from 'antd';
export class PropertyList extends React.Component {
constructor(){
super();
this.columns = [
{
title: 'Address',
dataIndex: 'street',
key: 'street',
render: text => <a>{text}</a>,
},
{
title: 'City',
dataIndex: 'city',
key: 'city',
},
{
title: 'State',
dataIndex: 'state',
key: 'state',
},
{
title: 'Workflow',
key: 'workflow',
dataIndex: 'workflow',
sorter: (a, b) => a.workflow.length - b.workflow.length,
sortDirections: ['descend'],
render: workflow => {
let color = 'geekblue';
if (workflow === 'Inspection' || workflow === 'Maintenance' || workflow === 'Cleaning') {
color = 'volcano';
}
else if (workflow === 'Rented') {
color = 'green';
}
return (
<span>
<Tag color={color} key={workflow}>
{workflow.toUpperCase()}
</Tag>
</span>
);
},
},
{
title: 'Action',
key: 'action',
render: (text, record) => (
<span>
<a>Edit</a>
<Divider type="vertical" />
<Popconfirm
title="Are you sure?"
onConfirm={this.confirm(record)}
onCancel={this.cancel}
okText="Yes"
cancelText="No"
>
Archive
</Popconfirm>
</span>
),
},
];
}
confirm = (record) => {
message.success('Archived');
console.log("confirm function.. record");
console.log(record);
}
cancel = () => {
message.error('Cancelled');
}
render() {
console.log("PropertyList render");
console.log(this.props);
console.log(this.props.properties);
console.log(this.columns);
return (
<div className="content-container">
<div className="list-body">
{
this.props.properties.length === 0 ? (
<div className="list-item list-item--message">
<span>No properties. Add some!</span>
</div>
) : (
<Table
rowKey="id"
dataSource={this.props.properties}
columns={this.columns}
pagination = { false }
footer={() => ''}
/>
)
}
</div>
</div>
)
}
};
const mapStateToProps = (state) => {
console.log("PropertyList mapStateToProps..");
console.log(state);
return {
properties: selectProperties(state.properties, state.filters)
};
};
const mapDispatchToProps = (dispatch) => ({
updateProperty: (id, property) => dispatch(editProperty(id, property))
});
export default connect(mapStateToProps, mapDispatchToProps)(PropertyList);
you are invoking the method confirm (in onConfirm) immediately when it renders the Table rows.
Change:
onConfirm={this.confirm(record)}
To:
onConfirm={() => this.confirm(record)}

Getting error while showing hiding React Table columns - React JS

I am working on React Table. I am basically a beginner in React. I have a dashboard page where I display a React Table of 8 columns. I have a customize button which will open a popup page, this popup page has 8 check boxes allows me to show/hide those React columns. Initially all the check boxes in this popup page is set to true. When I uncheck a column that particular column get disabled.
There are images in the end to see what I am trying to do.
I will be using this logic for show hide columns (this question was asked by me two days back) -
How to show and hide some columns on React Table?
The React Table data is like this
const columns = [
{
Header: 'Column 1',
accessor: 'firstName',
},
{
Header: 'Column 2',
accessor: 'firstName',
},
{
Header: 'Column 3',
accessor: 'firstName',
},
{
Header: 'Column 4',
accessor: 'firstName',
},
{
Header: 'Column 5',
accessor: 'firstName',
},
{
Header: 'Column 6',
accessor: 'firstName',
},
{
Header: 'Column 7',
accessor: 'firstName'
},
{
Header: 'Column 8',
accessor: 'firstName',
}
];
The start of the dashboard page
class Dashboard extends Component {
constructor(props) {
super(props);
this.state = {
filterState: {},
searchText: '',
isFilterOpen: false,
isCustomizedOpen: false,
isFiltered: false,
isSearched: false,
searchedTableData: [],
filteredTableData: [],
};
this.handleCustClickinv = this.handleCustClickinv.bind(this);
}
This is my code in the render function of my dashboard page for showing the customize button (this is written in parent dashboard page)
{this.state.isCustomizedOpen && <CustomizedView
filterState={this.state.filterState}
applyFilter={(values, clear) => { this.applyFilters(values, clear); }}
/>}
This is the code for the customize button (this is written in parent dashboard page)
<div className="custom-div-dashboard" onClick={() => { this.handleCustClickinv(); }}>
<div className='customize-view-dashboard'>Customized View </div>
</div>
This is function to handle the click on customize button (this is written in parent dashboard page)
handleFilterClickinv() {
if(this.state.isCustomizedOpen) {
this.setState({ isCustomizedOpen: false });
}
const currentState = this.state.isFilterOpen;
this.setState({ isFilterOpen: !currentState });
}
This is my entire popup page which will have 8 check boxes
import React, { Component } from 'react';
import PropTypes from 'prop-types';
import { bindActionCreators } from 'redux';
import { connect } from 'react-redux';
import { ActionCreators } from '../../../actions';
import './enqCustomizedView.scss';
import ButtonComponent from '../../shared/button/ButtonComponent';
import { CheckBox } from '../../shared/chkbox/CheckBox';
class CustomizedView extends Component {
constructor(props) {
super(props);
this.state = {
items: [
{ id: 1, value: 'Column 1', isChecked: true },
{ id: 2, value: 'Column 2', isChecked: true },
{ id: 3, value: 'Column 3', isChecked: true },
{ id: 4, value: 'Column 4', isChecked: true },
{ id: 5, value: 'Column 5', isChecked: true },
{ id: 6, value: 'Column 6', isChecked: true },
{ id: 7, value: 'Column 7', isChecked: true },
{ id: 8, value: 'Column 8', isChecked: true },
]
};
this.handleCheckChildElement = this.handleCheckChildElement.bind(this);
}
handleClick() {
this.setState({ isChecked: !this.state.isChecked });
}
handleCheckChildElement(event) {
//let items = this.state.items;
let { items } = this.state;
items.forEach(items = () => {
if(items.value === event.target.value) {
items.isChecked = event.target.checked;
}
});
this.setState({ items });
const column1checked = items[0].isChecked;
console.log('column1checked ' + column1checked);
const column2checked = items[1].isChecked;
console.log('column2checked ' + column2checked);
const column3checked = items[2].isChecked;
console.log('column3checked ' + column3checked);
const column4checked = items[3].isChecked;
console.log('column4checked ' + column4checked);
const column5checked = items[4].isChecked;
console.log('column5checked ' + column5checked);
const column6checked = items[5].isChecked;
console.log('column6checked ' + column6checked);
const column7checked = items[6].isChecked;
console.log('column7checked ' + column7checked);
const column8checked = items[7].isChecked;
console.log('column8checked ' + column8checked);
}
render() {
return (
<div className='popup-page-custom' >
<div className='bottomBar'>
<ButtonComponent
text='Apply'
className='activeButton filterMargin'
width='100'
display='inline-block'
onClick={() => { this.props.applyFilter(this.state, false); }}
/>
<ButtonComponent
text='Clear Filter'
className='greyedButton clear-filter'
width='100'
display='block'
marginTop='60'
onClick={() => { this.props.applyFilter(this.state, true); }}
/>
</div>
<div>
<div className='data-points-text'>
<span> Columns </span>
</div>
<div className="App">
<ul>
{
this.state.items.map((item, i) => {
return (<div key={i} ><CheckBox handleCheckChildElement={this.handleCheckChildElement} {...item} /></div>);
})
}
</ul>
</div>
</div>
</div>
);
}
}
CustomizedView.propTypes = {
applyFilter: PropTypes.func.isRequired
};
CustomizedView.defaultProps = {
};
function mapStateToProps(state) {
return {
auth: state.auth
};
}
function mapDispatchToProps(dispatch) {
return bindActionCreators(ActionCreators, dispatch);
}
export default connect(mapStateToProps, mapDispatchToProps)(CustomizedView);
And ultimately this is my checkbox page
import React from 'react';
import PropTypes from 'prop-types';
export const CheckBox = (props) => {
// super(props);
return (
<li>
<input key={props.id} onClick={props.handleCheckChildElement} type="checkbox" checked={props.isChecked} value={props.value} /> {props.value}
</li>
);
};
CheckBox.propTypes = {
id: PropTypes.string,
handleCheckChildElement: PropTypes.func,
isChecked: PropTypes.bool,
value: PropTypes.string,
};
CheckBox.defaultProps = {
id: '',
handleCheckChildElement: null,
isChecked: null,
value: '',
};
export default CheckBox;
This is a very basic (ugly) style of my dashboard page and popup page
This is the error I am getting on Chrome when unchecking the checkboxes
Edit 1 - As per Alireza Yadegari's suggestion, I made a 1 line change. But I am still getting 2 errors.
Edit 2 - As per Alireza Yadegari's suggestion, I applied console.
you have to use this piece of code in your constructor
this.handleCheckChildElement = this.handleCheckChildElement.bind(this)
let { items } = { ...this.state };
this is wrong ....
firstly you destructuring array to object then saying give me items prop from given object... of course this is wrong
const { items} = this.state;
takes items prop from the state
and finally.... implement your task with foreach is bad idea...
CheckBox.defaultProps = {
id: '',
handleCheckChildElement: null,
isChecked: null, value: '',
};
i don't understand what it does. you know?
I think your project is a sample and no need for further examples.
I just say about your mistakes.
first, when you are using methods it is good to use 'bind(this)' to show react where is the method belongs.
secondly, when you are using state, react just allows you to change it in the constructor and wherever you want to change it you have to use 'setState' method (you can read the reason for this in react documentation).
finally, if you have an array in your state you have to get an array in some temp object change the temp object and then apply changes with 'setState' method. if you have more question please feel free to ask.

Each record in table should have a unique `key` prop,or set `rowKey` to an unique primary key

I am rendering a table with ant design and it works fine, but there is a warning in the console:
Each record in table should have a unique key prop,or set rowKey
to an unique primary key
My code is as follows:
import React, { Component } from 'react';
import { Table} from 'antd';
import { adalApiFetch } from '../../adalConfig';
class ListTenants extends Component {
constructor(props) {
super(props);
this.state = {
data: []
};
}
fetchData = () => {
adalApiFetch(fetch, "/Tenant", {})
.then(response => response.json())
.then(responseJson => {
if (!this.isCancelled) {
const results= responseJson.map(row => ({
ClientId: row.ClientId,
ClientSecret: row.ClientSecret,
Id: row.Id,
SiteCollectionTestUrl: row.SiteCollectionTestUrl,
TenantDomainUrl: row.TenantDomainUrl
}))
this.setState({ data: results });
}
})
.catch(error => {
console.error(error);
});
};
componentDidMount(){
this.fetchData();
}
render() {
const columns = [
{
title: 'Client Id',
dataIndex: 'ClientId',
key: 'ClientId'
},
{
title: 'Site Collection TestUrl',
dataIndex: 'SiteCollectionTestUrl',
key: 'SiteCollectionTestUrl',
},
{
title: 'Tenant DomainUrl',
dataIndex: 'TenantDomainUrl',
key: 'TenantDomainUrl',
}
];
return (
<Table columns={columns} dataSource={this.state.data} />
);
}
}
export default ListTenants;
Just add a unique key value in tag link this:
<Table
columns={columns}
dataSource={this.state.data}
rowKey="Id" /> // unique key
Hope this help
React renders lists using the key prop. It works so because react allows you to reduce the complexity of diffing algorithms and reduce the number of DOM mutations. You can read a bit more in react reconciliation docs: https://reactjs.org/docs/reconciliation.html
In your case, you added the keys to the columns, but not for rows. Add the key field to the data source. So your code could be the following:
import React, { Component } from 'react';
import { Table} from 'antd';
import { adalApiFetch } from '../../adalConfig';
class ListTenants extends Component {
constructor(props) {
super(props);
this.state = {
data: []
};
}
fetchData = () => {
adalApiFetch(fetch, "/Tenant", {})
.then(response => response.json())
.then(responseJson => {
if (!this.isCancelled) {
const results= responseJson.map(row => ({
key: row.id, // I added this line
ClientId: row.ClientId,
ClientSecret: row.ClientSecret,
Id: row.Id,
SiteCollectionTestUrl: row.SiteCollectionTestUrl,
TenantDomainUrl: row.TenantDomainUrl
}))
this.setState({ data: results });
}
})
.catch(error => {
console.error(error);
});
};
componentDidMount(){
this.fetchData();
}
render() {
const columns = [
{
title: 'Client Id',
dataIndex: 'ClientId',
key: 'ClientId'
},
{
title: 'Site Collection TestUrl',
dataIndex: 'SiteCollectionTestUrl',
key: 'SiteCollectionTestUrl',
},
{
title: 'Tenant DomainUrl',
dataIndex: 'TenantDomainUrl',
key: 'TenantDomainUrl',
}
];
return (
<Table columns={columns} dataSource={this.state.data} />
);
}
}
export default ListTenants;
React Table unique key / rowKey
Each record in table should have a unique key prop,or set rowKey to an unique primary key.
solution 1
each col has a unique key
// each column with unique key
import React from 'react';
import {
Table,
} from 'antd';
const leftTableColumns = [
{
title: 'Page / Modal',
dataIndex: 'pageModal',
key: 'pageModal',
},
{
title: 'Success Rate',
dataIndex: 'successRate',
key: 'successRate',
},
];
const LeftTable = (props) => {
const {
leftTableDatas,
} = props;
return (
<>
<Table
columns={leftTableColumns}
dataSource={leftTableDatas}
/>
</>
);
};
export {
LeftTable,
};
export default LeftTable;
solution 2
only need set rowkey on the table with the unique value
// table with rowkey
import React from 'react';
import {
Table,
} from 'antd';
const leftTableColumns = [
{
title: 'Page / Modal',
dataIndex: 'pageModal',
},
{
title: 'Success Rate',
dataIndex: 'successRate',
},
];
const LeftTable = (props) => {
const {
leftTableDatas,
} = props;
return (
<>
<Table
// shorthand rowKey
rowKey="id"
// rowKey={obj => obj.id}
columns={leftTableColumns}
dataSource={leftTableDatas}
/>
</>
);
};
export {
LeftTable,
};
export default LeftTable;
ref
https://ant.design/components/table/
only you need set rowkey on the table with the unique value.
<Table
dataSource={[finance]}
columns={columns}
rowKey={record => record.id}
/>
Because you are not adding key to dataSource array, add a key in that also.
Like this:
const results= responseJson.map(row => ({
key: row.ClientId, // here
ClientId: row.ClientId,
ClientSecret: row.ClientSecret,
Id: row.Id,
SiteCollectionTestUrl: row.SiteCollectionTestUrl,
TenantDomainUrl: row.TenantDomainUrl
}))
Or you can use any unique value of dataSource array as key by using property rowKey, like this:
<Table
columns={columns}
dataSource={this.state.data}
rowKey="Id" /> // any unique value
Doc Reference.
for me worked this solution
rowKey="{record => record.id}"
or rowKey="id"
but in your collection have to exist the id column
I had your problem and this method answered
<Table
columns={columns}
dataSource={data}
rowKey="name"
/>
I have the same issue but solved with this, Hope this help :)
just add rowKey='id'
I use rowKey = 'id' because 'id' is unique data in variable dataSource, but you can use another unique value from variable dataSource. (with unique value)
import React from 'react'
import { Table } from 'antd'
const committeInformation = () => {
const columns = [
{
key: '0',
title: 'id',
dataIndex: 'id',
},
{
key: '1',
title: 'name',
dataIndex: 'name',
},
{
key: '2',
title: 'email',
dataIndex: 'email'
}
]
const dataSource = [
{
id: '1',
name: 'user 1',
email: 'coco#gmail.com',
},
{
id: '2',
name: 'user 2',
email: 'coco#gmail.com'
}
]
return (
<Table
rowKey='id' //this from variable dataSource
columns={columns}
dataSource={dataSource}
/>
)
}
export default committeInformation
Fast hack
I do assign random math numbers changed to string on each key.?
This is to say my columns become
const columns = [
{
title: 'Client Id',
dataIndex: 'ClientId',
key: () => Math.random().toString(),
},
{
title: 'Site Collection TestUrl',
dataIndex: 'SiteCollectionTestUrl',
key: () => Math.random().toString(),
},
{
title: 'Tenant DomainUrl',
dataIndex: 'TenantDomainUrl',
key: () => Math.random().toString(),
}
];
Hope this helps anybody visiting from the future..........
If your data has no logical key and you only need the key for presentation purposes, you could intercept the data and write a key in using a random number.
export const Table = ({
data,
}: {
data: ITableData[] | undefined;
}) => {
....
if (data) {
data.map((record) => {
return (record.id = Math.floor(Math.random() * 1000000));
});
and then assign the rowkey to the table
<Table dataSource={data} rowKey="id">
in Vue 3:
<a-table
...
:columns="yourColumns"
:data-source="yourData"
// the solution:
:row-key="record => record.id"
// or
:rowKey="record => record.id"
>

Resources