2

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})
  }
2
  • 1
    DON'T answer this dude's quesiton. I just spent a lot of time helping him and he didn't give any credit unless I made all the changes for him. I deleted my answer. Commented Oct 13, 2021 at 4:53
  • Hey @joseph, fixing the eslint errors didn't fix my problem, that's why I have created the fork, if you can see becuse I am de structuring the object, the array methods are not working correctly, when console logged it's repeating the elements it's adding that was my issue. I was just waiting for other answers I hope you understand. Commented Oct 13, 2021 at 4:59

1 Answer 1

1

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'));

Sign up to request clarification or add additional context in comments.

1 Comment

This is awesome thank you @zerocewl ! I have not considered declaring columns outside and just putting it inside my state as initialColumns, that's why it was hard for me to perform the relevant array methods on onChange. The docs about includes() was very helpful thanks!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.