TanStack 表| 如何在示例中使用 onPaginationChange 中的 redux 操作而不是 setPaginationState

Kos*_* GL 5 typescript react-table redux-toolkit

使用此示例
https://tanstack.com/table/v8/docs/examples/react/pagination-control
我如何使用https://tanstack.com/table/v8/docs/api/features/pagination#onpaginationchange如果我需要调度我的 redux 操作而不是 useState - setPaginationState?

onPaginationChange: state => dispatch(browseItemModalActions.setPagination(state))
Run Code Online (Sandbox Code Playgroud)

在控制台中出现此错误:

`react_devtools_backend.js:4012 A non-serializable value was detected in an action, in the path: `payload`. Value: old => {
          let newState = functionalUpdate(updater, old);
          return newState;
        } 
Run Code Online (Sandbox Code Playgroud)

Lin*_*ste 16

这是个有趣的问题!

根据示例使用的方式,onPaginationChange: setPagination您可能会认为该onPaginationChange函数是使用新状态调用的,但事实并非如此。

您的onPaginationChange函数实际上是通过“更新程序”函数调用的,该函数采用先前的状态并返回新的状态。这适用于 ReactsetState函数,因为它们支持功能更新,您可以将新状态定义为先前状态的函数。

换句话说,当你看到这个时:

onPaginationChange: setPagination,
Run Code Online (Sandbox Code Playgroud)

你认为它是这样做的:

onPaginationChange: (state) => setPagination(state),
Run Code Online (Sandbox Code Playgroud)

但它实际上是这样做的:

onPaginationChange: (updater) => setPagination(prevState => updater(prevState)),
Run Code Online (Sandbox Code Playgroud)

这是react-table源代码的相关部分:

setPagination: updater => {
  const safeUpdater: Updater<PaginationState> = old => {
    let newState = functionalUpdate(updater, old)

    return newState
  }

   return table.options.onPaginationChange?.(safeUpdater)
},
Run Code Online (Sandbox Code Playgroud)

GitHub 源代码


updater在 Redux 操作中使用此功能并不明显或容易。Redux 减速器是它们自己的“更新器”,并且操作必须采用原始数据。

最终,您可能需要考虑将这些数据存储在 Redux 中是否真的有意义。我确实有一些解决方法,但它们有其局限性。

  1. 您可以将分页状态保留在组件中,并使用挂钩将更改同步回 Redux useEffect,但这是一种单向同步,如果 Redux 分页状态的更改可能来自其他操作,则该同步将不起作用。
const reduxPagination = useSelector((state) => state.counter.pagination);

const [pagination, setPagination] = React.useState(reduxPagination);

const { pageIndex, pageSize } = pagination;

const dispatch = useDispatch();

useEffect(() => {
  dispatch(browseItemModalActions.setPagination(pagination));
}, [pagination, dispatch]);
Run Code Online (Sandbox Code Playgroud)
onPaginationChange: setPagination,
Run Code Online (Sandbox Code Playgroud)
  1. 您可以将更新程序应用到之前从 Redux 中选择的状态和dispatch更新后的值。
const pagination = useSelector((state) => state.counter.pagination);

const dispatch = useDispatch();

const table = useReactTable({
  state: {
    pagination
  },
  onPaginationChange: (updater) => {
    const nextState = updater(pagination);
    dispatch(browseItemModalActions.setPagination(nextState));
  },
  manualPagination: true,
...
Run Code Online (Sandbox Code Playgroud)

但现在我的头要爆炸了,因为我收到一个 TypeScript 错误,告诉我这updater可能是一个函数,也可能是一个值……但我们只是查看了源代码,它始终是一个函数!所以我不知道该怎么办了。这让我想知道react-table源代码是否有错误,回调是否意味着允许纯数据值。

  • 这非常有帮助,并且比文档解释得更好!看起来 Updater 的类型还是很奇怪,在我的版本中添加了一个检查: ``` const setPagination: OnChangeFn&lt;PaginationState&gt; = (updater) =&gt; { if (typeof updater === 'function') { const nextState = updater (分页) setPaginationState(nextState) } } ``` (2认同)