React-table: Server-side filtering with a fully controlled react-table

Created on 20 Dec 2017  路  6Comments  路  Source: tannerlinsley/react-table

What version of React-Table are you using?

version of react-table: "6.7.5"

What bug are you experiencing, or what feature are you proposing?

Hi,
I have a strange behavior when I try to use server-side filtering with a fully controlled react-table component. The onFetchData callback is called twice : a first time with the previous value of state.filtered and a second time with the value I type in a filter. My backend sends me back the right filtered values but the react table component is not updated properly.

Use https://codesandbox.io/s/y3vw3x8jz to reproduce the issue.

What are the steps to reproduce the issue?

1) Type a character in a filter area
2) Notice in the console that onFetchData callback is called twice

Thanks for your help !

Most helpful comment

@tonix-tuft we faced the same problem so we wrapped the onFilteredChange callback function in the lodash debounce function (https://lodash.com/docs/4.17.11#debounce).
So the table is as follows:

<ReactTable
   {...props}
   onFilteredChange={debounce(onColumnFilterChange, 1000)}
/>

The AJAX call is made 1 second (1000ms) after a filter change is detected. The debouncing isn't cumulative, so even if the user enters multiple characters only one call will be made after the time has elapsed (unless the user types one character per second aha).

All 6 comments

remove filtered={this.state.filtered} and the double call will go away

filtered and onFilteredChange are related - but they are not required to both be there to get the filtering to work (especially if you are going to be filtering server-side - which is one of the main purposes of onFetchData - along with server-side sorting, and pagination).

In fact, if you are going to filter server side, the filtered information is already passed in the state parameter of the onFetchData call (as are the sorting and pagination information). So it is like one big handler function for all of the "controlled" separate functions.

Thanks for your answer Gary.

In fact I would like to initialise a column of my react-table with a default filter, that's why I used filtered={this.state.filtered}. I don't think I can achieve this without using filtered.

Maybe I'm not using the component correctly:

For example , let's say I want a default filter on the column "lastName" with the value "test".

I update the state with: this.setState(filtered : [{id:lastName,value:test}])

Then, when I type 16 in the "age" column the onFilteredChange callback is called and filtered is now equals to [{id:lastName,value:test}, {id:age,value:16}].

Finally I have the double call issue I describe above, in onFetchData callback.

So how can I have my values filtered with my default filter if I don't use filtered={this.state.filtered} to update my table ?

Thanks

There's going to be a bit of conflict in doing that. The doco on onFetchData says...

"If you want to handle pagination, sorting, and filtering on the server, react-table makes it easy on you."

So, the assumption is that onFetchData is used to control the filtering server side. So what you would need to do is NOT pass your filter information to ReactTable - but have that state used to set that up on the first call to onFetchData (at least that is the approach I would take).

You can sort of mix and match these two ways - but in your case I don't think it is possible (you could end up in a bit of a loop)

The problem with onFetchData is that if I type fast within a column filter input, I get too many AJAX calls fired. Is there a way to mitigate this?

@tonix-tuft we faced the same problem so we wrapped the onFilteredChange callback function in the lodash debounce function (https://lodash.com/docs/4.17.11#debounce).
So the table is as follows:

<ReactTable
   {...props}
   onFilteredChange={debounce(onColumnFilterChange, 1000)}
/>

The AJAX call is made 1 second (1000ms) after a filter change is detected. The debouncing isn't cumulative, so even if the user enters multiple characters only one call will be made after the time has elapsed (unless the user types one character per second aha).

That's pretty cool. I resolved in a similar way by wrapping the onColumnFilterChange function with another one which starts an interval and clears a previous one with setInterval (I guess that's how debounce works too).

Was this page helpful?
0 / 5 - 0 ratings

Related issues

JayV30 picture JayV30  路  26Comments

ivanov-v picture ivanov-v  路  16Comments

sshaginyan picture sshaginyan  路  21Comments

Oskii2311 picture Oskii2311  路  46Comments

ggascoigne picture ggascoigne  路  18Comments