Using query params with ReactTable

3k Views Asked by At

I have a react table that looks more or less like this:

<ReactTable
          ref={tableRef}
          style={{ minHeight: "80vh" }}
          className="-highlight -striped  text-center"
          data={data}
          loading={isLoading}
          loadingText={getLoadingMessage("Fetching users...")}
          noDataText="No users found..."
          columns={getColumns()}
          filterable={false}
          minRows={0}
          pageSizeOptions={[10, 13, 20, 50, 100]}
          defaultPageSize={10}
          onFetchData={tableState => getUsers({ tableState, searchValue })}
/>

I want to use query params so that I can have in my link, depending on the page and rows, something like this ?page=3&rows=50. How can I implement this using hooks?

This is how getUsers looks like:

getUsers: thunk(async (actions, { tableState, searchValue }) => {
    actions.setIsLoading(true);

    let QUERIES = getQueryParamsFromTable(tableState, searchValue);

    try {
      const { data } = await api.get(urlParamReplacer(AUTH.USERS), {
        params: QUERIES
      });
      actions.setUsers(data);
    } catch (error) {
      actions.setIsLoading(false);
      console.error(error);
    }
  }),

and this is setIsLoading:

setIsLoading: action((state, payload) => {
    state.isLoading = payload;
  }),
1

There are 1 best solutions below

7
On BEST ANSWER

You can create a custom hook to return the query parameters or implement the use-query-params library.

With the use-query-params library, it can be implemented with the following code:

const [query, setQuery] = useQueryParams({
  page: NumberParam,
  rows: NumberParam,
});
const [page, setPage] = useState(query.page || 0);

<ReactTable
  ref={tableRef}
  style={{ minHeight: "80vh" }}
  className="-highlight -striped  text-center"
  data={data}
  loading={isLoading}
  loadingText={getLoadingMessage("Fetching users...")}
  noDataText="No users found..."
  columns={getColumns()}
  filterable={false}
  minRows={0}
  pageSizeOptions={[10, 13, 20, 50, 100]}
  defaultPageSize={10}
  page={page}
  pageSize={query.rows}
  onPageChange={pageIndex => setPage(pageIndex)}
  onFetchData={tableState => getUsers({ tableState, searchValue })}
/>

Here is an example with a custom hook:

import { useState, useEffect } from "react";
import { useLocation, useHistory } from 'react-router-dom';

const usePagination = (initialPage = 0, initialRows = 50) => {
  const location = useLocation();
  const searchParams = new URLSearchParams(location.search);
  const history = useHistory();

  const [page, updatePage] = useState(Number(searchParams.get("page")) || initialPage);
  const [rows, updateRows] = useState(Number(searchParams.get("rows")) || initialRows);

  useEffect(() => {
    const searchParams = new URLSearchParams(location.search);
    
    updatePage(Number(searchParams.get('page')) || page);
    updateRows(Number(searchParams.get('rows')) || rows);
  }, [location, page, rows]);

  const setPage = toPage => {
    searchParams.set("page", toPage || initialPage);
    history.push({ search: searchParams.toString() });
  };

  const setRows = toRows => {
    searchParams.set("rows", toRows || initialRows);
    history.push({ search: searchParams.toString() });
  };

  return {
    page,
    rows,
    setPage,
    setRows
  };
};

export default usePagination;
const { page, rows, setPage, setRows } = usePagination();

<ReactTable
  ref={tableRef}
  style={{ minHeight: "80vh" }}
  className="-highlight -striped  text-center"
  data={data}
  loading={isLoading}
  loadingText={getLoadingMessage("Fetching users...")}
  noDataText="No users found..."
  columns={getColumns()}
  filterable={false}
  minRows={0}
  pageSizeOptions={[10, 13, 20, 50, 100]}
  defaultPageSize={10}
  page={page}
  pageSize={rows}
  onPageChange={pageIndex => setPage(pageIndex)}
  onPageSizeChange={(pageSize, pageIndex) => {
    setPage(pageIndex);
    setRows(pageSize);
  }}
  onFetchData={tableState => getUsers({ tableState, searchValue })}
/>