我有一个创建 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/