Using this example
https://tanstack.com/table/v8/docs/examples/react/pagination-controlled
How can I use https://tanstack.com/table/v8/docs/api/features/pagination#onpaginationchange if I need to dispatch my redux action instead of useState - setPaginationState?
onPaginationChange: state => dispatch(browseItemModalActions.setPagination(state))
getting this error in console:
`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;
}
This is an interesting question!
Based on the way that the example uses onPaginationChange: setPagination
you might think that the onPaginationChange
function gets called with the new state, but it does not.
Your onPaginationChange
function actually gets called with an "updater" function which takes the previous state and returns the new state. This works with React setState
functions because they support functional updates where you define your new state as a function of the previous state.
In other words, when you see this:
onPaginationChange: setPagination,
You think it's doing this:
onPaginationChange: (state) => setPagination(state),
But it's actually doing this:
onPaginationChange: (updater) => setPagination(prevState => updater(prevState)),
Here's the relevant part of the react-table source code:
setPagination: updater => {
const safeUpdater: Updater<PaginationState> = old => {
let newState = functionalUpdate(updater, old)
return newState
}
return table.options.onPaginationChange?.(safeUpdater)
},
It is not obvious or easy to use this updater
function in a Redux action. Redux reducers are "updaters" of their own, and the actions must take raw data.
Ultimately, you may need to think about whether it really makes sense to store this data in Redux. I do have some workarounds but they have their limitations.
useEffect
hook, but this is a one-way syncing and won't work if changes to the Redux pagination state can come from other actions.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]);
onPaginationChange: setPagination,
dispatch
the updated value.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,
...
But now my head is exploding because I'm getting a TypeScript error telling me that updater
could be either a function or a value...but we just looked at the source code and it's always a function! So I don't know what to make of this anymore. It makes me wonder if the react-table
source code is a mistake and the callback is meant to allow plain data values.