This is the code I am trying to rebuild using functional component, but my arrays do not behave correctly.
EXPECTED RESULT: https://stackblitz.com/edit/antd-showhidecolumns
My forked functional component version: MY WORK https://stackblitz.com/edit/antd-showhidecolumns-rdyc8h
Main issue here is I am not able to show/hide column cells, I am not sure why my array is different when I use the same method as the original code.
My code:
const onChange = (e) => {
let { checkedColumns } = colmenu;
if (e.target.checked) {
checkedColumns = checkedColumns.filter((id) => {
return id !== e.target.id;
});
console.log('if checked columns is', checkedColumns);
} else if (!e.target.checked) {
checkedColumns.push(e.target.id);
console.log('elseif checked columns', checkedColumns);
}
const filtered = checkedColumns.filter((el) => {
return el.dataIndex !== checkedColumns.el;
});
console.log('filtered items', filtered);
setColmenu({ ...colmenu, columns: filtered });
};
working version from the old code (class component)
onChange = (e) => {
var checkedColumns = this.state.checkedColumns
if(e.target.checked){
checkedColumns = checkedColumns.filter(id => {return id !== e.target.id})
}
else if(!e.target.checked){
checkedColumns.push(e.target.id)
}
var filtered = this.state.initialColumns;
for(var i =0;i< checkedColumns.length; i )
filtered = filtered.filter(el => {return el.dataIndex !== checkedColumns[i]})
this.setState({columns: filtered, checkedColumns: checkedColumns})
}
CodePudding user response:
Something really went wrong with your code (or homework i guess?)
Please have a look at least at the docs for React.useState to set some basics.
First you should init your initalColumns
and later you should filter on them.
Additional i init the checkColumns
with the correct values and changed the wrong logic for changing them.
Have a look how the filtering is done via Array.includes maybe someone will ask for this ;-)
Another point is that you may split the state object in separate primitive states.
Nevertheless here is a working stackblitz and the depending code.
import React from 'react';
import ReactDOM from 'react-dom';
import 'antd/dist/antd.css';
import './index.css';
import { Table, Button, Dropdown, Menu, Checkbox } from 'antd';
const App = () => {
const columns = [
{
title: 'Description',
dataIndex: 'description',
},
{
title: 'Employees',
dataIndex: 'employees',
},
];
const [colmenu, setColmenu] = React.useState({
value: false,
checkedColumns: ['description', 'employees'],
visibleMenuSettings: false,
columns,
initialColumns: columns,
});
const onChange = (e) => {
let { checkedColumns, columns, initialColumns } = colmenu;
if (!e.target.checked) {
checkedColumns = checkedColumns.filter((id) => {
return id !== e.target.id;
});
console.log('if checked columns is', checkedColumns);
} else if (e.target.checked) {
checkedColumns.push(e.target.id);
console.log('elseif checked columns', checkedColumns);
}
console.log(columns);
columns = initialColumns.filter((col) =>
checkedColumns.includes(col.dataIndex)
);
setColmenu({ ...colmenu, columns, checkedColumns });
};
const handleVisibleChange = (flag) => {
setColmenu({ ...colmenu, visibleMenuSettings: flag });
};
const menu = (
<Menu>
<Menu.ItemGroup title="Columns">
<Menu.Item key="0">
<Checkbox id="description" onChange={onChange} defaultChecked>
Description
</Checkbox>
</Menu.Item>
<Menu.Item key="1">
<Checkbox id="employees" onChange={onChange} defaultChecked>
Employees
</Checkbox>
</Menu.Item>
</Menu.ItemGroup>
</Menu>
);
const dataSource = [
{
key: '1',
description: 'Holiday 1',
employees: '79',
},
{
key: '2',
description: 'Holiday 2',
employees: '12',
},
{
key: '3',
description: 'Holiday 3',
employees: '0',
},
];
return (
<div>
<div className="row">
<div className="col-12 mb-3 d-flex justify-content-end align-items-center">
<Dropdown
overlay={menu}
onVisibleChange={handleVisibleChange}
visible={colmenu.visibleMenuSettings}
>
<Button>Show/Hide Columns</Button>
</Dropdown>
</div>
</div>
<div className="row">
<div className="col-12">
<Table
columns={colmenu.columns}
dataSource={dataSource}
size="small"
pagination={{
pageSizeOptions: ['20', '50'],
showSizeChanger: true,
}}
/>
</div>
</div>
</div>
);
};
ReactDOM.render(<App />, document.getElementById('container'));