Home > Mobile >  antd table filter does not unfilter after deleting search query
antd table filter does not unfilter after deleting search query

Time:08-10

I am attempting to create a simple filter mechanism for data in an antd table component. The filter is triggered by the onChange event in an antd search input.

I have managed to get the filter to work correctly when typing into the search input, but when I delete the initial input I don't get my original table results back. It's as if the state is not updating after the most recent onChange event.

This example demonstrates precisely what I am trying to do, but it is mapping some data to elements instead of using an antd table. This leads me to think there is something I am missing specifically when it comes to filtering data in an antd table.

This example also demonstrates what I am trying to do, but it is implemented as a class, so I'm having some trouble translating the logic over to my functional component. Particularly on line 128 I'm seeing the map function again, but I don't understand what's happening there.

I would also like to add that I did not experience this problem with the same implementation using a basic html table with map function to insert the data.

Here is my code:

export default function DriversModal({ isVisible, handleClose }) {
  const initialUserData = [
    { type: 2, user: { name: 'TestName1', username: '[email protected]'}, phone: '(123) 456-1111', ops: 37 },
    { type: 1, user: { name: 'TestName2', username: '[email protected]'}, phone: '(123) 456-2222', ops: 16 },
    { type: 2, user: { name: 'TestName3', username: '[email protected]'}, phone: '(123) 456-3333', ops: 4 },
    { type: 1, user: { name: 'TestName4', username: '[email protected]'}, phone: '(123) 456-4444', ops: 52 }
  ]

  const columns = [
    {
      title: 'Name',
      dataIndex: 'user',
      render: (user) => (
        <>
          <div className="list-modal-cell-text-primary">{user.name}</div>
          <div className="list-modal-cell-text-secondary">{user.username}</div>
        </>
      ),
      width: 320,
      key: '1',
    },
    {
      title: 'Phone',
      dataIndex: 'phone',
      width: 144,
      key: '2',
    },
    {
      title: 'Ops',
      dataIndex: 'ops',
      key: '3',
    },
  ];

  const [users, setUsers] = useState(initialUserData);
  const [query, setQuery] = useState('');

  const handleChange = (e) => {
    setQuery(e.target.value);
  }

  useEffect(() => {
    setUsers(users.filter(item =>
      item.user.name.toLowerCase().includes(query.toLowerCase()) ||
      item.user.username.toLowerCase().includes(query.toLowerCase())
    ))
  }, [query, users])

  return (
    <Modal
      title={<DriversModalHeader handleChange={handleChange} handleSort={handleSort} query={query} />}
      bodyStyle={{ height: '264px'}}
      visible={isVisible}
      closable={false}
      destroyOnClose={true}
      footer={[
        <Button
          onClick={handleClose}
        >
          Close
        </Button>
      ]}
    >
      <Table
        dataSource={users}
        columns={columns}
        pagination={false}
        scroll={{
          y: 240,
        }}
        row
      />
    </Modal>
  )
}

DriversModalHeader:

export default function DriversModalHeader({ handleChange, handleSort, query }) {
  const menu = (
    <Menu>
      <Menu.Item key="availability" onClick={handleSort}>Sort by availability</Menu.Item>
      <Menu.Item key="alphabetic" onClick={handleSort}>Sort alphabetically</Menu.Item>
    </Menu>
  )

  return (
    <div className="list-modal-header">
      <div className="title">
        <div className="title">
          Drivers
        </div>
      </div>
      <div className="elements">
        <div className="list-modal-input-with-button">
          <Input.Search
            value={query}
            placeholder="Search"
            onChange={handleChange}
          />
          <span className="icon">
            <Icon component={Search} style={{fontSize: '16px'}} />
          </span>
        </div>
        <div className="list-modal-dropdown">
          <StateSelect />
        </div>
        <div>
          <Dropdown.Button
            placement={"bottomRight"}
            className="union"
            overlay={menu}
            trigger={['click']}
            icon={<Icon component={Union} style={{fontSize: '24px'}}/>}
          >
          </Dropdown.Button>
        </div>
      </div>
    </div>
  );
};

CodePudding user response:

I just checked the first example you mentioned.

As you said, it doesn't unfilter after deleting the search query.
The reason is simple. It's because the app should have to filter the data with empty string from initial data but instead it's trying to filter data that you already filtered with search query.

So the solution is replace "users.filter ... " with "initialUserData.filter ..." on useEffect hook.

  useEffect(() => {
    setUsers(
      users.filter( //replace with initialUserData.filter
        (item) =>
          item.user.name.toLowerCase().includes(search.toLowerCase()) ||
          item.user.username.toLowerCase().includes(search.toLowerCase())
      )
    ); }, [search, users]);

I hope it will be helpful for you.

  • Related