Using redux action in the onPaginationChange function instead of setPaginationState in the given example for the TanStack table - is there a way to

Provided this sample

Is there a way to utilize by dispatching a redux action rather than using useState - setPaginationState?

onPaginationChange: state => dispatch(browseItemModalActions.setPagination(state))

An error is appearing in the 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;
        } 

Answer №1

What an intriguing question!

When looking at the example's usage of

onPaginationChange: setPagination
, one might assume that the onPaginationChange function is invoked with the new state, but this is not the case.

The onPaginationChange function actually receives an "updater" function, which takes the previous state and returns the new state. This mechanism aligns with React's setState functionality, as it supports functional updates where the new state is defined based on the previous state.

In essence, instead of interpreting this:

onPaginationChange: (state) => setPagination(state),

It operates like this:

onPaginationChange: (updater) => setPagination(prevState => updater(prevState)),

The relevant snippet from the react-table source code is provided below:

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

    return newState
  }

   return table.options.onPaginationChange?.(safeUpdater)
},

GitHub Source


Using the updater function within a Redux action can be challenging and may not be straightforward. Redux reducers act as their own updaters, and actions should handle raw data.

It's important to consider whether storing this data in Redux truly makes sense. There are potential workarounds, albeit with limitations.

  1. You can maintain the pagination state within the component and synchronize changes back to Redux using a useEffect hook. However, this method only facilitates one-way syncing and may not accommodate changes from other actions affecting the Redux pagination state.
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,
  1. An alternative approach involves applying the updater to the previously selected state from Redux and then dispatching 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,
...

However, confusion arises when encountering a TypeScript error indicating that updater could potentially be either a function or a value. Despite our examination of the source code confirming it to always be a function, this inconsistency raises uncertainty regarding whether the react-table callback should indeed accept plain data values.

Answer №2

Implement a function to manage pagination changes passed through props

export function CustomDataTable({
  columns,
  data,
  onPageChange,//Pagination callback
}) {

const table = useReactTable({
    data,
    columns,
    getCoreRowModel: fetchCoreRowModel(),
    getPaginationRowModel: retrievePaginationRowModel(),
  });

const currentPageIndex = table.getState().pagination.pageIndex;

useEffect(() => {
  onPageChange && onPageChange(currentPageIndex);
}, [currentPageIndex]);

Utilize the useEffect hook to monitor changes in the current page index and execute the onPageChange callback when it is modified.

Example

<CustomDataTable
  columns={columns}
  data={event.data}
  onPageChange={console.log}
/>

Answer №3

If you're looking to easily retrieve the new page index and size without using additional React.useState, this solution might work for you.

The onPaginationChange callback accepts an updater as a parameter, allowing you to simply invoke it to obtain the updated values.

onPaginationChange: (updater) => {
  // Ensure that updater is callable (to prevent TypeScript warnings)
  if (typeof updater !== "function") return;

  const newPageInfo = updater(table.getState().pagination);

  console.log(table.getState().pagination);
  // Output: {pageIndex: 0, pageSize: 30}

  console.log(newPageInfo);
  // Output: {pageIndex: 1, pageSize: 30}
}

In addition, by typing newPageInfo. in VSCode, you'll benefit from code completion suggestions.

This approach has been tested on version 8 of react-table.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Unable to successfully transfer a document

I am looking to upload a file onto my server. Here is what I have attempted: <input (change)="uploadImage($event.target)" hidden accept="image/*" #uploadProfileImage type="file"> uploadImage(event) { const profileImage = event.files.item(0); t ...

Using Mat-Error for Two Way Binding leads to frequent triggering of ngModelChange事件

I am working with a mat input field that has two-way data binding using ngModel, and I want to add validation using mat-error and formControl. <mat-form-field [formGroup]="myForm"> <input matInput formControlName="myFormName" autocomplete="off" ...

Is there a simple method I can use to transition my current react.js project to typescript?

I am currently working on a project using react.js and am considering converting it to typescript. I attempted following an article on how to make this conversion but have run into numerous bugs and issues. Is there a simpler method for doing this conver ...

How can the return type of a function that uses implicit return type resolution in Typescript be displayed using "console.log"?

When examining a function, such as the one below, my curiosity drives me to discover its return type for educational purposes. function exampleFunction(x:number){ if(x < 10){ return x; } return null } ...

A step-by-step guide on creating a Decorator using the TypeScript compile API

How can I create a custom class in TypeScript with multiple 'class-validator' decorators to ensure the property types are correct? I am considering using `ts.factory.createDecorator`, but I'm unsure how to obtain a `ts.Expression` for it. ...

Angular: Initiate multiple functions simultaneously and combine results afterwards

My current code successfully zips and saves the response of a JSON array by splitting them into individual files using a single method. zip: JSZip = new JSZip(); folder: JSZip = new JSZip(); this.apicall.api1() .subscribe( response => { for (let r ...

Begin the NextJS project by redirecting the user to the Auth0 page without delay

I am new to coding and currently working on a project using Typescript/NextJS with Auth0 integration. The current setup navigates users to a page with a login button that redirects them to the Auth0 authentication page. However, this extra step is unneces ...

Tips for integrating Tailwind CSS into Create React App using React

I recently started using tailwindcss with my react app. I tried to follow the guide from tailwindcss but encountered various issues and bugs along the way. If anyone has advice on how to successfully start a project using tailwind and react, I would apprec ...

Guide on integrating angular-schema-form into an Ionic 2.0 project using typescript

Recently, I embarked on creating an app with Ionic from scratch and decided to integrate the framework. While I faced no issues executing the example on a webpage, I encountered difficulties when attempting to do so with Ionic. To kickstart the project, ...

Customizing font color upon hover in Next.js and Tailwind.css

Recently, I developed a Navbar component that displays a purple link when navigating to pages like Home or Projects. The issue arises when the background color is light; in this case, the link turns green on hover instead of staying purple. How would I adj ...

What is the necessity of requiring a parameter with the type "any"?

There is a function in my code that takes a single parameter of type any: function doSomething(param: any) { // Code to handle the param } When I call this function without passing any arguments: doSomething(); An error is thrown saying: "Expected 1 ...

Guide to customizing Material UI theme using Typescript in a separate file

Trying to customize Material UI theme overrides can be a bit tricky, as seen in the example below: // theme.ts const theme: Theme = createMuiTheme({ overrides: { MuiButton: { root: { display: 'inline-block', fontWeigh ...

Combining Repetitive Elements in an Array

Trying to combine an array of products with the same order_id while also including all objects from a second products array. Below are some sample orders: const orders = [ { "order_details": { }, "order_id": "1", ...

I need to access the link_id value from this specific actionid and then execute the corresponding function within the Ionic framework

I have a JavaScript code in my TypeScript file. It retrieves the attribute from a span element when it is clicked. I want to store this attribute's value in a TypeScript variable and then call a TypeScript function. Take a look at my ngOnInit method, ...

Is there a way to verify the presence of multiple array indices in React with TypeScript?

const checkInstruction = (index) => { if(inputData.info[index].instruction){ return ( <Text ref={instructionContainerRef} dangerouslySetInnerHTML={{ __html: replaceTextLinks(inputData.info[index].instruction) ...

Passing both the object and its attributes simultaneously for reflect-metadata in TypeScript is a feature that closely resembles functionality found

Instead of using DataAnnotation in C# to add meta attributes on properties, I am seeking a similar functionality in TypeScript for a ldap model class. The goal is to have decorators that can set the LDAP attribute used in the LDAP directory internally. ex ...

Enhance a subject's behavior by overriding the .next method using a decorator

Currently, I am working on an Angular application where I have numerous Subjects, BehaviorSubjects, and ReplaySubjects as properties in various services. I am attempting to create a TypeScript decorator that can be added to some of these Subjects to enhanc ...

Tips for sharing data between two components

In my project, I have a customized Shared Component which consists of an input search bar with a "continue" button. This Shared Component is being utilized within two other components - the buy component and sell component. The challenge I am encountering ...

Record the success or failure of a Protractor test case to generate customized reports

Recently, I implemented Protractor testing for our Angular apps at the company and I've been searching for a straightforward method to record the pass/fail status of each scenario in the spec classes. Is there a simple solution for this? Despite my at ...

Angular 5 encountering issue with @Injectable annotation causing TypeScript error

While trying to compile my code, I encountered the following error: import { HttpClient } from '@angular/common/http'; import { Injectable } from '@angular/core'; @Injectable() export class TaskService { constructor(private http: Ht ...