React 表 - 下拉过滤器

Gar*_*y S 1 react-table

我已经使用 setGlobalFilter 实现了全局文件管理器

在此输入图像描述

但我想明智地设置过滤器列,例如:

在表之外,我需要一个包含一些值的下拉列表,这些值应该根据下拉列表中选择的值来过滤反应表。此下拉过滤器应根据下拉列表中选择的值过滤掉整个表。

在此输入图像描述

任何人都可以给我演示链接或任何有关此的帮助将不胜感激。

yoh*_*nes 6

好吧,我们在react-table v8上做一下,是的,它是react-table的新版本。

首先,确保您从以下位置导入所需的项目@tanstack/react-table

import {
  createColumnHelper,
  flexRender,
  getCoreRowModel,
  getFilteredRowModel,
  useReactTable,
} from "@tanstack/react-table";
Run Code Online (Sandbox Code Playgroud)

在这里,我们使用简单的数据。

const defaultData = [
  {
    firstName: "tanner",
    lastName: "linsley",
    age: 24,
    visits: 100,
    status: "In Relationship",
    progress: 50,
  },
  {
    firstName: "tandy",
    lastName: "miller",
    age: 40,
    visits: 40,
    status: "Single",
    progress: 80,
  },
  {
    firstName: "joe",
    lastName: "dirte",
    age: 45,
    visits: 20,
    status: "Complicated",
    progress: 10,
  },
];
Run Code Online (Sandbox Code Playgroud)

在新版本的react-table中,我们不必记住。我们可以借助columnHelper来定义它。您可以在此处阅读详细信息。


const columnHelper = createColumnHelper();

const columns = [
  columnHelper.accessor("firstName", {
    header: "First Name",
  }),
  columnHelper.accessor("lastName", {
    header: "Last Name",
  }),
  columnHelper.accessor("age", {
    header: "Age",
  }),
  columnHelper.accessor("visits", {
    header: "Visits",
  }),
  columnHelper.accessor("status", {
    header: "Status",
  }),
  columnHelper.accessor("progress", {
    header: "Profile Progress",
  }),
];
Run Code Online (Sandbox Code Playgroud)

接下来,我们在组件中定义所需的状态。

  const [data] = useState(() => [...defaultData]);

  // to keep the selected column field
  const [field, setField] = useState();

  // to keep the input search value
  const [searchValue, setSearchValue] = useState("");

  // required by react-table for filtering purposes
  const [columnFilters, setColumnFilters] = useState();
Run Code Online (Sandbox Code Playgroud)

在之前的版本中,我们使用useTable hooks 来创建表实例,在新版本中,我们使用useReactTable代替。我们通过这些配置来使我们的过滤器正确运行。

  const table = useReactTable({
    data,
    columns,
    enableFilters: true,
    enableColumnFilters: true,
    getCoreRowModel: getCoreRowModel(),
    getFilteredRowModel: getFilteredRowModel(),
    state: {
      columnFilters,
    },
    onColumnFiltersChange: setColumnFilters,
  });
Run Code Online (Sandbox Code Playgroud)

接下来,我们创建选择选项标签,将选择选项绑定到字段状态,并将onChange事件处理程序绑定到handleSelectChange。对于输入标记,我们将绑定到searchValue,并将onChange事件处理程序绑定到handleInputChange方法。在选择更改处理程序内,我们需要重置columnFilterssearchValue状态。

  ...

  const handleSelectChange = (e) => {
    setColumnFilters([]);
    setSearchValue("");
    setField(e.target.value);
  };

  const handleInputChange = (e) => {
    setSearchValue(e.target.value);
  };

  return (
    ...
      <select value={field} onChange={handleSelectChange}>
        <option value="">Select Field</option>
        {table.getAllLeafColumns().map((column, index) => {
          return (
            <option value={column.id} key={index}>
              {column.columnDef.header}
            </option>
          );
        })}
      </select>
      <input
        value={searchValue}
        onChange={handleInputChange}
        className="p-2 font-lg shadow border border-block"
        placeholder={
          field ? `Search ${field} column...` : "Please select a field"
        }
      />
   ...
 )
Run Code Online (Sandbox Code Playgroud)

在这里,我们从table.getAllLeafColumns()获取了选择选项列表。

由于列agevisitsprogress值为数字,我们需要使用自定义filterFn选项修改列配置。

const columns = [
  ...

  columnHelper.accessor("age", {
    header: "Age",
    filterFn: (row, _columnId, value) => {
      return row.original.age === parseInt(value);
    },
  }),
  columnHelper.accessor("visits", {
    header: "Visits",
    filterFn: (row, _columnId, value) => {
      return row.original.visits === parseInt(value);
    },
  }),

  ...

  columnHelper.accessor("progress", {
    header: "Profile Progress",
    filterFn: (row, _columnId, value) => {
      return row.original.progress === parseInt(value);
    },
  }),
];
Run Code Online (Sandbox Code Playgroud)

正如文档所说,我们需要记住这一点:

每个过滤器函数接收:

  1. 要过滤的行
  2. 用于检索行值的columnId
  3. 过滤值

如果该行应包含在过滤行中,则应返回 true,如果应删除该行,则应返回 false。

最后,是时候渲染表格了:

  return (
    <div className="p-2">
      ...

      <table>
        <thead>
          {table.getHeaderGroups().map((headerGroup) => (
            <tr key={headerGroup.id}>
              {headerGroup.headers.map((header) => (
                <th key={header.id}>
                  {header.isPlaceholder
                    ? null
                    : flexRender(
                        header.column.columnDef.header,
                        header.getContext()
                      )}
                </th>
              ))}
            </tr>
          ))}
        </thead>
        <tbody>
          {table.getRowModel().rows.map((row) => (
            <tr key={row.id}>
              {row.getVisibleCells().map((cell) => (
                <td key={cell.id}>
                  {flexRender(cell.column.columnDef.cell, cell.getContext())}
                </td>
              ))}
            </tr>
          ))}
        </tbody>
      </table>
    </div>
  );
Run Code Online (Sandbox Code Playgroud)

这是工作代码:

编辑 sleepy-poitras-6brjuc

我希望它有帮助。