如何在表格列的Filter组件中获取另一列的筛选值?
Problem Statement
I have the following column definitions in React Table:
columns: [ { Header: "A", accessor: "a", id: "a", Cell: ({ value }) => value, filterMethod: (filter, row) => { // My filter logic }, Filter: ({ filter, onChange }) => { // How to get column B's filter value here? return ( // My filter component ); }, }, { Header: "B", accessor: "b", id: "b", Cell: ({ value }) => value, filterMethod: (filter, row) => { // My filter logic }, Filter: ({ filter, onChange }) => { return ( // My filter component ); }, }, ];
I need to retrieve another column's filter value inside a custom Filter component (e.g., get column B's value in column A's Filter), and update one filter component based on changes in another. The Filter function currently only receives column, filter, and onChange props, which are specific to the current column.
Solution 1: Use Global Filters State from useTable
React Table's useTable hook returns a state.filters array that holds the filter state for all columns. You can access this array and find the target column's filter value using its ID.
First, define your columns inside the component where you call useTable—this lets them access the table's state and methods:
import { useTable, useFilters } from "react-table"; function MyTable() { const data = /* Your table data */; // Destructure filters and setFilter from useTable const { getTableProps, getTableBodyProps, headerGroups, rows, prepareRow, state: { filters }, setFilter, // Use this to update other column filters if needed } = useTable( { columns: [ { Header: "A", accessor: "a", id: "a", Cell: ({ value }) => value, filterMethod: (filter, row) => { // Example filter logic return row.a?.includes(filter.value); }, Filter: ({ filter, onChange }) => { // Get column B's filter value const columnBFilter = filters.find(f => f.id === "b"); const columnBValue = columnBFilter ? columnBFilter.value : ""; return ( <div> <input type="text" value={filter.value || ""} onChange={(e) => onChange(e.target.value)} placeholder="Filter column A" /> {/* Optional: Display column B's value for testing */} <p>Column B's filter value: {columnBValue}</p> </div> ); }, }, { Header: "B", accessor: "b", id: "b", Cell: ({ value }) => value, filterMethod: (filter, row) => { // Example filter logic return row.b?.includes(filter.value); }, Filter: ({ filter, onChange }) => { const handleChange = (e) => { const newValue = e.target.value; onChange(newValue); // Optional: Sync column A's filter with column B's value setFilter("a", newValue); }; return ( <input type="text" value={filter.value || ""} onChange={handleChange} placeholder="Filter column B" /> ); }, }, ], data, }, useFilters // Don't forget to include the useFilters plugin ); // Render your table structure below return ( <table {...getTableProps()}> <thead> {headerGroups.map(headerGroup => ( <tr {...headerGroup.getHeaderGroupProps()}> {headerGroup.headers.map(column => ( <th {...column.getHeaderProps()}> {column.render("Header")} {/* Render filter component */} <div>{column.canFilter ? column.render("Filter") : null}</div> </th> ))} </tr> ))} </thead> <tbody {...getTableBodyProps()}> {rows.map(row => { prepareRow(row); return ( <tr {...row.getRowProps()}> {row.cells.map(cell => ( <td {...cell.getCellProps()}>{cell.render("Cell")}</td> ))} </tr> ); })} </tbody> </table> ); }
Solution 2: Use getFilter from useFilters
The useFilters plugin provides a getFilter function that lets you directly retrieve the filter state for a specific column by its ID. This is a cleaner approach if you only need the value of one specific column.
import { useTable, useFilters } from "react-table"; function MyTable() { const data = /* Your table data */; const { getTableProps, getTableBodyProps, headerGroups, rows, prepareRow, getFilter, // Retrieve this from useTable setFilter, } = useTable( { columns: [ { Header: "A", accessor: "a", id: "a", Cell: ({ value }) => value, filterMethod: (filter, row) => row.a?.includes(filter.value), Filter: ({ filter, onChange }) => { // Get column B's filter value directly const columnBValue = getFilter("b")?.value || ""; return ( <div> <input type="text" value={filter.value || ""} onChange={(e) => onChange(e.target.value)} placeholder="Filter column A" /> <p>Column B's current filter: {columnBValue}</p> </div> ); }, }, { Header: "B", accessor: "b", id: "b", Cell: ({ value }) => value, filterMethod: (filter, row) => row.b?.includes(filter.value), Filter: ({ filter, onChange }) => ( <input type="text" value={filter.value || ""} onChange={(e) => onChange(e.target.value)} placeholder="Filter column B" /> ), }, ], data, }, useFilters ); // Render table structure here (same as Solution 1) }
Key Notes
- Always define columns inside the component where you call
useTable—this ensures they have access to the table's state and methods. - Use
setFilterto update another column's filter value when you need to sync filters between columns. - The
filtersarray contains objects withid(matching your column'sid) andvalue(the current filter value for that column).
内容的提问来源于stack exchange,提问作者Sabbiu Shah

