reactjsreact-table-v7

Showing the new row in react-table on the current page


I have been playing with ReactTable v7 for a while and have encountered the following problem: when the table is sorted and uses paginator sometimes adding (or editing) a row causes it to be outside the current page.

You can see the problem here: https://codesandbox.io/s/github/tannerlinsley/react-table/tree/master/examples/material-UI-kitchen-sink

  1. Sort the table by First Name
  2. Press add
  3. Enter a record with First Name "zzzzz"

The record is added but is currently hidden which confuses users. Is there a "standard" way to fix the issue? Am I missing something?

In v6 I have done a workaround for it:

    React.useEffect(() => {
        if (editedElementId && reactTable) {
            const { data } = reactTable.props;

            if (data && data.length > 0) {
                const internal = reactTable.getResolvedState();

                let position = -1;
                internal.sortedData.forEach((row, i) => {
                    if (row._original.id === editedElementId) position = i;
                });

                if (position >= 0) {
                    const pageNumber = Math.floor(position / pageSize);
                    setPage(pageNumber);
                } else {
                    alert.info("Element not visible");
                }
            }
        }
    }, [editedElementId]);

...

    <ReactTable
       ref={(r) => {setReactTable(r);}}
...

But maybe there is a bulit-in way to achieve it?


Solution

  • There is not currently a way to only sort the elements which are currently being displayed, no.

    React Table v7's useSortBy hook sorts the entirety of the input data array, so sorting by First Name descending (A->Z) naturally places 'ZZZZZZ' at the end of the list, which will be hidden due to pagination. The v7 way of doing it would probably be similar to what you are doing already, using the exposed properties from the useTable hook instead of reactTable.resolvedState() and etc. Another way to do it would be to write your own custom sortBy method and only sort the items [0...n] where n is the number of currently displayed items.

    As a side note, since the autoResetSortBy property is true by default in the example you linked, the step of sorting on First Name is irrelevant -- since the function which adds a new user to the list mutates the data array, the sorting method is reset. That function appends the new user to the end of the list, so it will always be on a new page, even if the "Rows per page" option is set to "All". Both issues can be fixed by setting autoResetSortBy to false, and changing the pageSize in addUserHandler.