reactjs - 如何停止共享 react-table v7 useTable 状态?

标签 reactjs react-table-v7

我有一个创建 react 表的组件,当只涉及一个页面时,它按预期工作:

const ReactTable = (props) => {
    const {data, columns, viewState, updateViewState} = props;

    const defaultColumn = React.useMemo(() => ({
        Filter: DefaultColumnFilter,
        updateFiltering: (column, newValue) => updateFiltering(viewState, updateViewState, column, newValue),
        filter: 'standard',
        canResize: true}),[]);

    const {filters, filterable, groupBy, expanded, page} = viewState;

    const tableInstance = useTable(
        {
            columns,
            data,
            defaultColumn,
            autoResetExpanded: false,
            groupByFn: (rows, columnId) => {
                const getKey = value => value.label ? value.label: value;
                return rows.reduce((prev, row) => {
                    const resKey = `${getKey(row.values[columnId])}`;
                    prev[resKey] = Array.isArray(prev[resKey]) ? prev[resKey] : [];
                    prev[resKey].push(row);
                    return prev}, {})},
            filterTypes: {'standard': applyFilter},
            pageSize: page.size,
            initialState: {filters, groupBy, expanded, pageIndex: page.index}},
        useFilters,
        useGroupBy,
        useExpanded,
        usePagination,
        useRowSelect,
        addSelectColumn);

    const {getTableProps, getTableBodyProps, setGroupBy} = tableInstance;

    React.useEffect(
        () => updateViewStateFromTable(viewState, tableInstance, updateViewState));

    if (!isEqual(groupBy, tableInstance.state.groupBy)) setGroupBy(groupBy);

    const headerRows = getHeaderRows(tableInstance, viewState, updateViewState);
    const dataRows = getDataRows(tableInstance);
    const filterRow = getFilterRow(tableInstance, viewState);

    console.log('ReactTable', {props, tableInstance})
    return (
        <div>
            <table className="ReactTable -highlight rt-table"
                   {...getTableProps()}>
                <thead className="rt-thead -header">
                    {headerRows}
                </thead>
                <tbody className="rt-tbody" {...getTableBodyProps()}>
                    {(filterable)? filterRow:null}
                    {dataRows}
                </tbody>
                <PaginationFoot {...{viewState, tableInstance}} />
            </table>
            <h2>viewState:</h2>
            <pre>
                <code>
                    {JSON.stringify({viewState}, null, 4)}
                </code>
            </pre>
        </div>)};

export default ReactTable;

不幸的是,如果我在一个页面上更改页面索引或大小,它也会影响所有其他页面。

“viewState”是我的构造,用于跟踪和保留过滤器、分页、扩展、列选择、分组和排序(并允许用户创建他们自己的自定义命名 View 状态)。

看起来表的内部状态正在被破坏性地修改,因为 viewState 副本显示了正确的分页数据(但在呈现后更新为不正确的共享值)。

我尝试使用 useControlledState 直接进入/离开 viewState,但这会导致错误,因为它试图在渲染操作期间更新状态。

最佳答案

由于表状态是一种状态,因此该行为在技术上是正确的。这里的麻烦是,当数据和viewState发生变化时,我想有效地重新挂载react table组件(或者重新初始化它的状态)。

有一个“表格页面”,上面有组件,它的属性正在改变,因此有一个不同的表格规范和数据内容被提供给它。

路由将每个/table/:tableName 路由到同一个 TablePage,该 TablePage 向其 ReactTable 组件提供数据和 viewState。因此 useTable 内部状态被重新用于每个表,这导致了问题。

一个冗长的解决方法只是为每个表格页面添加一个组件(而不是仅仅更改数据)从这里更改我的路由表:

const routeMap = [
  {path: '/', component: Dashboard, allowAny},
  {path: '/login', component: LoginOrOut, allowAny},

  {path: "/table/:tableName", component: TablePage},
  {path: "/tables", component: Tables},
  {path: "/new/:modelType", component: RoutedModel, action: 'new'},
  ...

为此:

const routeMap = [
  {path: '/', component: Dashboard, allowAny},
  {path: '/login', component: LoginOrOut, allowAny},

  ...tableNames.map(tableName =>
      ({path: `/table/${tableName}`, component: props => <TablePage tableName={tableName} {...props} />})),

  {path: "/tables", component: Tables},
  {path: "/new/:modelType", component: RoutedModel, action: 'new'},
  ...

这感觉很笨拙,因为我正在创建一个更大的 DOM,以便组件可以保持自己的状态,但它看起来很高效。

关于reactjs - 如何停止共享 react-table v7 useTable 状态?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65572146/

相关文章:

javascript - 默认导出后 React 组件为 null

android - uri 图像未在 React native ImageView 中呈现

javascript - 使用外部 react 组件缺少 react

reactjs - 如何向React Table InminatedCheckbox方法添加类型

javascript - ReactTable v7 - noDataText 未显示在空数据上(使用 useTableHook)

javascript - 在 React Table 7.1.0 中一次只能选择一行

javascript - 单击全选按钮后检查/取消选中复选框的 reducer 功能 -redux React

javascript - SyntaxError : react-table/src/publicUtils. js:当前未启用对实验语法 'jsx' 的支持

react-table - 如何从 v7 (React-Table) 中的列访问另一列的值