【发布时间】:2022-08-18 17:43:20
【问题描述】:
我对 react-table v8 过滤器进行了稍微修改的实现:https://tanstack.com/table/v8/docs/examples/react/filters
在原版中,他们似乎使用自定义过滤器函数来全局过滤表,但它需要另一个我不想包含的库,文档对此不是很清楚,但似乎有内置函数我可以使用:https://tanstack.com/table/v8/docs/api/features/filters
但是,一旦更改表格,表格就会停止过滤,我尝试不包括globalFilterFn,并将其设置为globalFilterFn: \"includesString\",这是我提到的内置功能之一,但到目前为止没有任何效果。
这是我的代码:
import React from \"react\";
import ReactDOM from \"react-dom/client\";
import \"./index.css\";
import {
useReactTable,
getCoreRowModel,
getFilteredRowModel,
getPaginationRowModel,
getSortedRowModel,
FilterFn,
ColumnDef,
flexRender
} from \"@tanstack/react-table\";
//import { RankingInfo, rankItem } from \"@tanstack/match-sorter-utils\";
import { makeData, Person } from \"./makeData\";
/* declare module \"@tanstack/table-core\" {
interface FilterMeta {
itemRank: RankingInfo;
}
}
const fuzzyFilter: FilterFn<any> = (row, columnId, value, addMeta) => {
// Rank the item
const itemRank = rankItem(row.getValue(columnId), value);
// Store the itemRank info
addMeta({
itemRank
});
// Return if the item should be filtered in/out
return itemRank.passed;
}; */
function App() {
const rerender = React.useReducer(() => ({}), {})[1];
const [globalFilter, setGlobalFilter] = React.useState(\"\");
const columns = React.useMemo<ColumnDef<Person>[]>(
() => [
{
header: \"Name\",
footer: (props) => props.column.id,
columns: [
{
accessorKey: \"firstName\",
cell: (info) => info.getValue(),
footer: (props) => props.column.id
},
{
accessorFn: (row) => row.lastName,
id: \"lastName\",
cell: (info) => info.getValue(),
header: () => <span>Last Name</span>,
footer: (props) => props.column.id
},
{
accessorFn: (row) => `${row.firstName} ${row.lastName}`,
id: \"fullName\",
header: \"Full Name\",
cell: (info) => info.getValue(),
footer: (props) => props.column.id
}
]
},
{
header: \"Info\",
footer: (props) => props.column.id,
columns: [
{
accessorKey: \"age\",
header: () => \"Age\",
footer: (props) => props.column.id
},
{
header: \"More Info\",
columns: [
{
accessorKey: \"visits\",
header: () => <span>Visits</span>,
footer: (props) => props.column.id
},
{
accessorKey: \"status\",
header: \"Status\",
footer: (props) => props.column.id
},
{
accessorKey: \"progress\",
header: \"Profile Progress\",
footer: (props) => props.column.id
}
]
}
]
}
],
[]
);
const [data, setData] = React.useState(() => makeData(500));
const refreshData = () => setData((old) => makeData(500));
const table = useReactTable({
data,
columns,
state: {
globalFilter
},
onGlobalFilterChange: setGlobalFilter,
//globalFilterFn: \"includesString\",
getCoreRowModel: getCoreRowModel(),
getFilteredRowModel: getFilteredRowModel(),
getSortedRowModel: getSortedRowModel(),
getPaginationRowModel: getPaginationRowModel()
});
return (
<div className=\"p-2\">
<div>
<input
value={globalFilter ?? \"\"}
onChange={(event) => setGlobalFilter(event.target.value)}
className=\"p-2 font-lg shadow border border-block\"
placeholder=\"Search all columns...\"
/>
</div>
<div className=\"h-2\" />
<table>
<thead>
{table.getHeaderGroups().map((headerGroup) => (
<tr key={headerGroup.id}>
{headerGroup.headers.map((header) => {
return (
<th key={header.id} colSpan={header.colSpan}>
{header.isPlaceholder ? null : (
<>
<div
{...{
className: header.column.getCanSort()
? \"cursor-pointer select-none\"
: \"\",
onClick: header.column.getToggleSortingHandler()
}}
>
{flexRender(
header.column.columnDef.header,
header.getContext()
)}
{{
asc: \" ????\",
desc: \" ????\"
}[header.column.getIsSorted() as string] ?? null}
</div>
</>
)}
</th>
);
})}
</tr>
))}
</thead>
<tbody>
{table.getRowModel().rows.map((row) => {
return (
<tr key={row.id}>
{row.getVisibleCells().map((cell) => {
return (
<td key={cell.id}>
{flexRender(
cell.column.columnDef.cell,
cell.getContext()
)}
</td>
);
})}
</tr>
);
})}
</tbody>
</table>
<div className=\"h-2\" />
<div className=\"flex items-center gap-2\">
<button
className=\"border rounded p-1\"
onClick={() => table.setPageIndex(0)}
disabled={!table.getCanPreviousPage()}
>
{\"<<\"}
</button>
<button
className=\"border rounded p-1\"
onClick={() => table.previousPage()}
disabled={!table.getCanPreviousPage()}
>
{\"<\"}
</button>
<button
className=\"border rounded p-1\"
onClick={() => table.nextPage()}
disabled={!table.getCanNextPage()}
>
{\">\"}
</button>
<button
className=\"border rounded p-1\"
onClick={() => table.setPageIndex(table.getPageCount() - 1)}
disabled={!table.getCanNextPage()}
>
{\">>\"}
</button>
<span className=\"flex items-center gap-1\">
<div>Page</div>
<strong>
{table.getState().pagination.pageIndex + 1} of{\" \"}
{table.getPageCount()}
</strong>
</span>
<span className=\"flex items-center gap-1\">
| Go to page:
<input
type=\"number\"
defaultValue={table.getState().pagination.pageIndex + 1}
onChange={(e) => {
const page = e.target.value ? Number(e.target.value) - 1 : 0;
table.setPageIndex(page);
}}
className=\"border p-1 rounded w-16\"
/>
</span>
<select
value={table.getState().pagination.pageSize}
onChange={(e) => {
table.setPageSize(Number(e.target.value));
}}
>
{[10, 20, 30, 40, 50].map((pageSize) => (
<option key={pageSize} value={pageSize}>
Show {pageSize}
</option>
))}
</select>
</div>
<div>{table.getPrePaginationRowModel().rows.length} Rows</div>
<div>
<button onClick={() => rerender()}>Force Rerender</button>
</div>
<div>
<button onClick={() => refreshData()}>Refresh Data</button>
</div>
<pre>{JSON.stringify(table.getState(), null, 2)}</pre>
</div>
);
}
const rootElement = document.getElementById(\"root\");
if (!rootElement) throw new Error(\"Failed to find the root element\");
ReactDOM.createRoot(rootElement).render(
<React.StrictMode>
<App />
</React.StrictMode>
);
CodeSanbox 的链接:https://codesandbox.io/s/long-monad-652jcm?file=/src/main.tsx
我在 React 方面仍然非常缺乏经验,甚至在打字稿方面更缺乏经验,所以也许我遗漏了一些明显的东西。
我是否误解了文档,也许自定义功能是必要的?
标签: reactjs react-table