React-table: Page reset

Created on 22 Nov 2018  路  3Comments  路  Source: tannerlinsley/react-table

The page not reset after data object changed.
Example
User changed the page number 1 to 3 the table rows changed then user changed the custom filters and submitted, the data object and rows also changed but page still 3.

Most helpful comment

I'm experiencing this same problem. I'm using a custom onFetchData function to handle all my server-side pagination/sorting/etc. It works like a charm, _except_ for situations like the above case when I want to allow a user to use custom filter components to fetch new table data from the server.

For example, if a user is 3 pages into the table data and uses the custom filter component to fetch new data (filtered by new criteria) from the server, everything works successfully... but the table just displays that new data starting at page 3, rather than resetting back to page 1 (like what happens when a user sorts by a column a few pages in). Trying to work around this and manually fix it has presented a new set of challenges, which I've touched on briefly below.

Said custom onFetchData function looks something like this:

  handleFetchTableDisplayData = (state) => {
    this.setState(prevState => {
      return {
        isTableLoading: true,
        paginationData: {
          ...prevState.paginationData,
          pageSize: state.pageSize,
          page: state.page
        },
        ...(state.sorted.length > 0 && {
          currentSelectedFilterValues: {
            ...prevState.currentSelectedFilterValues,
            sortable: {
              sortByColumn: state.sorted[0].id,
              ascendingSort: !state.sorted[0].desc
            }
          }
        })
      }
    }, this.fetchDataFromServer);
  }

I have a separate handler for my filter search button, which tries to reset the page back to 0 (which is not currently working):

  handleClickFilterSearch = () => {
    this.setState(prevState => {
      return {
        isTableLoading: true,
        paginationData: {
          ...prevState.paginationData,
          pageIndex: 0 // Manually reset page count back to first page on filter search
        }
      }
    }, this.fetchDataFromServer);
  };

The fetchDataFromServer function in both of the above functions builds the filters/page count and makes the AJAX call to the server to return the page count data. This is roughly what it looks like:

function fetchDataFromServer() {
  const selectedFilters = {
      filters: this.state.filters,
      recordLimit: this.state.paginationData.pageSize,
      offset: this.state.paginationData.pageIndex * this.state.paginationData.pageSize
  } 

    this.searchByFilters(selectedFilters)
      .then(response => {
        this.setState(prevState => {
          return {
            isTableLoading: false,
            paginationData: {
              ...prevState.paginationData,
              pages: response.totalItemSize > 0 ? Math.ceil(response.totalItemSize / prevState.paginationData.pageSize) : 1,
              totalItemCount: response.totalItemSize
            }
          }
        });
      })
}

Long story short, I've tried to work around this by trying to manually control just the page prop of the Table component, so I can manually reset it back to 0 when a user clicks my custom filter search button. Here's what my Table component looks like now:

      <Table
        cellAlignment={ALIGNMENT.LEFT}
        columns={props.columns}
        data={props.data}
        onPageChange={(pageIndex) => props.onPageChange(pageIndex)}
        onFetchData={props.onFetchData}
        loading={props.isTableLoading}
        pages={props.paginationData.pages}
        page={props.paginationData.pageIndex}
        defaultPageSize={props.paginationData.pageSize}
        striped
        manual
      />

However, this has opened up a _bunch_ of other issues that have made using my custom onFetchData function (handleFetchTableDisplayData) a lot more challenging, partially due to differences between the page value that comes from the state param and instance param that the react-table passes back to the custom onFetchData function. I have a rough example of some of these issues in this codesandbox link: https://codesandbox.io/s/323707m2o1

If I try to work around this by building in a custom handlePageChange function (that does nicely run before my handleFetchTableDisplayData function and can be seen above), I run into issues where now resetting the page back to 1 when a user sorts the table is no longer working. I'd love to continue using all the beautiful and easy functionality of onFetchData (which works wonderfully for 99% of my use-cases), but it's frustrating that it seems like I'll have to scrap all of this simply because using the custom filter doesn't reset the page back to 1.

I hope this helps clarify things. Please let me know if you have any questions (or suggestions!), or if there is any additional info I can provide. Thank you so much for your time!

All 3 comments

Do you have any example code that you can submit?

I'm experiencing this same problem. I'm using a custom onFetchData function to handle all my server-side pagination/sorting/etc. It works like a charm, _except_ for situations like the above case when I want to allow a user to use custom filter components to fetch new table data from the server.

For example, if a user is 3 pages into the table data and uses the custom filter component to fetch new data (filtered by new criteria) from the server, everything works successfully... but the table just displays that new data starting at page 3, rather than resetting back to page 1 (like what happens when a user sorts by a column a few pages in). Trying to work around this and manually fix it has presented a new set of challenges, which I've touched on briefly below.

Said custom onFetchData function looks something like this:

  handleFetchTableDisplayData = (state) => {
    this.setState(prevState => {
      return {
        isTableLoading: true,
        paginationData: {
          ...prevState.paginationData,
          pageSize: state.pageSize,
          page: state.page
        },
        ...(state.sorted.length > 0 && {
          currentSelectedFilterValues: {
            ...prevState.currentSelectedFilterValues,
            sortable: {
              sortByColumn: state.sorted[0].id,
              ascendingSort: !state.sorted[0].desc
            }
          }
        })
      }
    }, this.fetchDataFromServer);
  }

I have a separate handler for my filter search button, which tries to reset the page back to 0 (which is not currently working):

  handleClickFilterSearch = () => {
    this.setState(prevState => {
      return {
        isTableLoading: true,
        paginationData: {
          ...prevState.paginationData,
          pageIndex: 0 // Manually reset page count back to first page on filter search
        }
      }
    }, this.fetchDataFromServer);
  };

The fetchDataFromServer function in both of the above functions builds the filters/page count and makes the AJAX call to the server to return the page count data. This is roughly what it looks like:

function fetchDataFromServer() {
  const selectedFilters = {
      filters: this.state.filters,
      recordLimit: this.state.paginationData.pageSize,
      offset: this.state.paginationData.pageIndex * this.state.paginationData.pageSize
  } 

    this.searchByFilters(selectedFilters)
      .then(response => {
        this.setState(prevState => {
          return {
            isTableLoading: false,
            paginationData: {
              ...prevState.paginationData,
              pages: response.totalItemSize > 0 ? Math.ceil(response.totalItemSize / prevState.paginationData.pageSize) : 1,
              totalItemCount: response.totalItemSize
            }
          }
        });
      })
}

Long story short, I've tried to work around this by trying to manually control just the page prop of the Table component, so I can manually reset it back to 0 when a user clicks my custom filter search button. Here's what my Table component looks like now:

      <Table
        cellAlignment={ALIGNMENT.LEFT}
        columns={props.columns}
        data={props.data}
        onPageChange={(pageIndex) => props.onPageChange(pageIndex)}
        onFetchData={props.onFetchData}
        loading={props.isTableLoading}
        pages={props.paginationData.pages}
        page={props.paginationData.pageIndex}
        defaultPageSize={props.paginationData.pageSize}
        striped
        manual
      />

However, this has opened up a _bunch_ of other issues that have made using my custom onFetchData function (handleFetchTableDisplayData) a lot more challenging, partially due to differences between the page value that comes from the state param and instance param that the react-table passes back to the custom onFetchData function. I have a rough example of some of these issues in this codesandbox link: https://codesandbox.io/s/323707m2o1

If I try to work around this by building in a custom handlePageChange function (that does nicely run before my handleFetchTableDisplayData function and can be seen above), I run into issues where now resetting the page back to 1 when a user sorts the table is no longer working. I'd love to continue using all the beautiful and easy functionality of onFetchData (which works wonderfully for 99% of my use-cases), but it's frustrating that it seems like I'll have to scrap all of this simply because using the custom filter doesn't reset the page back to 1.

I hope this helps clarify things. Please let me know if you have any questions (or suggestions!), or if there is any additional info I can provide. Thank you so much for your time!

There are some edge cases for advanced state control like you are describing that are not supported in v6 right now. I would accept a PR to add/update/fix this functionality, but I would recommend waiting for v7 (a month or two). It will ship with a fully controllable and hoistable state module that shoulda allow the functionality that you're looking for.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

mellis481 picture mellis481  路  3Comments

ocalde picture ocalde  路  3Comments

dwjft picture dwjft  路  3Comments

tremby picture tremby  路  3Comments

bdkersey picture bdkersey  路  3Comments