如何在Material React Table初始化时维护筛选状态
实现Material React Table筛选状态持久化
要在组件初始化时恢复筛选状态(比如导航返回后),核心是将表格的筛选状态从非受控模式转为受控模式,再把状态持久化到本地存储(localStorage)或路由参数中。以下是两种实用方案:
方案一:LocalStorage本地持久化(适合单用户本地保存)
这种方式把筛选状态存在浏览器的localStorage里,用户刷新页面或导航返回后自动恢复:
import { useState, useEffect, useMemo } from 'react'; import MaterialReactTable from 'material-react-table'; const TaskTable = ({ rows }) => { // 从localStorage读取初始筛选状态,无数据则设为空对象 const initialFilterState = JSON.parse(localStorage.getItem('task-table-filters')) || {}; const [filterState, setFilterState] = useState(initialFilterState); // 筛选状态变化时,自动保存到localStorage useEffect(() => { localStorage.setItem('task-table-filters', JSON.stringify(filterState)); }, [filterState]); const columns = useMemo( () => [ { accessorKey: 'description', header: 'Description', filterVariant: 'text', size: 150, }, { accessorKey: 'task_type', header: 'Type', size: 90, filterVariant: 'multi-select', } ], [] ); return ( <MaterialReactTable columns={columns} data={rows} enableStickyHeader enablePinning initialState={{ density: 'compact' }} enableFacetedValues enableFilterMatchHighlighting // 启用受控筛选状态 filterState={filterState} onFilterChange={setFilterState} muiTablePaperProps={{ elevation: 0, sx: { borderRadius: '0' } }} muiTableContainerProps={{ sx: { maxHeight: '350px' } }} /> ); }; export default TaskTable;
方案二:路由参数持久化(适合分享筛选后的页面链接)
如果需要让用户能分享筛选后的表格链接,可把筛选状态存在路由的查询参数中:
import { useState, useEffect, useMemo } from 'react'; import { useSearchParams } from 'react-router-dom'; import MaterialReactTable from 'material-react-table'; const TaskTable = ({ rows }) => { const [searchParams, setSearchParams] = useSearchParams(); // 从路由参数解析初始筛选状态 const initialFilterState = searchParams.get('filters') ? JSON.parse(decodeURIComponent(searchParams.get('filters'))) : {}; const [filterState, setFilterState] = useState(initialFilterState); // 筛选状态变化时更新路由参数 useEffect(() => { if (Object.keys(filterState).length > 0) { setSearchParams({ filters: encodeURIComponent(JSON.stringify(filterState)) }); } else { // 清空筛选时移除路由参数 searchParams.delete('filters'); setSearchParams(searchParams); } }, [filterState, searchParams, setSearchParams]); const columns = useMemo( () => [ { accessorKey: 'description', header: 'Description', filterVariant: 'text', size: 150, }, { accessorKey: 'task_type', header: 'Type', size: 90, filterVariant: 'multi-select', } ], [] ); return ( <MaterialReactTable columns={columns} data={rows} enableStickyHeader enablePinning initialState={{ density: 'compact' }} enableFacetedValues enableFilterMatchHighlighting filterState={filterState} onFilterChange={setFilterState} muiTablePaperProps={{ elevation: 0, sx: { borderRadius: '0' } }} muiTableContainerProps={{ sx: { maxHeight: '350px' } }} /> ); }; export default TaskTable;
关键说明
- 必须使用
filterState和onFilterChange实现受控状态,替代仅依赖initialState的非受控模式,这样才能手动控制筛选状态的读取和保存。 - localStorage方案适合不需要分享的场景,路由参数方案支持跨会话或分享筛选结果。
- 如果有多张表格,建议给localStorage的key加上唯一标识(比如示例中的
task-table-filters),避免不同表格的筛选状态冲突。
内容的提问来源于stack exchange,提问作者Edmar Sanchez
相关产品推荐
相关产品推荐

