You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.17 09:02:26