39

I am using react-table v7 https://www.npmjs.com/package/react-table for creating tables.

  1. I am able to do sorting to all the columns by referring this example of sorting https://codesandbox.io/s/github/tannerlinsley/react-table/tree/master/examples/sorting . Now I dont want all columns to sort but some specfic columns and I want to sort 2 columns by default descending. Can someone please help me with this.

  2. After applying filters to the table I want to clear all the applied filters. Can someone please help in solving this issue too ?

Thank you

Blessy Julie
  • 899
  • 3
  • 8
  • 19

7 Answers7

70

The other answer given was for react-table that didn't use react hooks (< v7). In order to sort a column (or columns) when the table is built, you just have to set the sortBy array on the initialState in the useTable hook.

const {
    getTableProps,
    getTableBodyProps,
    ...
} = useTable(
    {
        columns,
        ....,
        initialState: {
            sortBy: [
                {
                    id: 'columnId',
                    desc: false
                }
            ]
        }
    }
Chuck L
  • 1,026
  • 10
  • 23
  • 5
    Just wanted to add that, according to the docs, the `sortBy` array should be *memoized* . Ref.: https://react-table.tanstack.com/docs/api/useSortBy#table-options – dglozano Feb 16 '21 at 09:05
  • You forgot to mention the mandatory `useSortBy` like here: https://stackoverflow.com/a/72436628/9714920 – Smily May 30 '22 at 15:22
8

you can pass sorted options to ReactTable please try with below code. And for clear try with button click call clear function.

  constructor(props) {
    super(props);
    this.state = {
      sortOptions: [{ id: 'age', desc: true },{ id: 'visits', desc: true }],
     }
  }

 <Table 
    sorted={this.state.sortOptions}
    onSortedChange={val => {
    this.setState({ sortOptions: val }) }}
    columns={columns} 
    data={data} />

It works for me https://codesandbox.io/s/stupefied-hoover-ibz6f

Oshini
  • 613
  • 4
  • 17
  • Thanks @Oshini for the reply . I tried to map id with the accessor but it didn't work . :( Can u help me with some other way please ? – Blessy Julie Feb 06 '20 at 12:13
  • did you go through the link https://codesandbox.io/s/stupefied-hoover-ibz6f . it display data was sorted by default. – Oshini Feb 06 '20 at 12:16
  • Yeah I did try the same thing, mapped id with the accessor but it didn't work :( – Blessy Julie Feb 06 '20 at 12:47
  • This solution doesn't work for react-table version using react-hooks. Please see my answer: https://stackoverflow.com/a/61278421/1571979 – Chuck L Apr 17 '20 at 18:37
  • Thanks a lot ! I sorted out the answer at-last ! About default Sort, I sorted the data of the table descending and got the data by-default as descending . And for clear button https://stackoverflow.com/questions/60279994/how-to-clear-all-filters-in-react-table , please do refer this link ! – Blessy Julie Feb 20 '20 at 17:14
7

For those using V8 and want to avoid the frustration I went to to find the answer in the docs, you simply provide your inital state into the useState that V8 uses for sorting:

Instead of the default:

const [sorting, setSorting] = useState<SortingState>([]);

You would do:

const [sorting, setSorting] = useState<SortingState>([
    {id: "time", desc: true}
]);
kev1n
  • 140
  • 1
  • 7
6

In Version 7. And while the top answer is good, it is not complete.

You need 2 things

  • useSortBy
  • Memorized list of columns to sort

A minimal example should include:

const sortees = React.useMemo(
  () => [
    {
      id: "firstName",
      desc: false
    }
  ],
  []
);

and also

import { useTable, useSortBy } from "react-table";
...
useTable(
  {
    initialState: {
      sortBy: sortees,
    }
  },
  useSortBy,
);

An example link: https://codesandbox.io/s/flamboyant-bassi-b94kyx?file=/src/App.js which includes minor changes to the official sort example

Smily
  • 2,732
  • 1
  • 15
  • 20
4

I had a slightly different use case and wanted to get multi-sorting by default on initial load, but then also keep that sorting order behind any future sorts

sandbox example here: https://codesandbox.io/s/goofy-shadow-9tskr?file=/src/App.js

The trick is NOT using the built in getSortByToggleProps() and instead adding your own onClick that uses the setSortBy func.

Below code inspired from @khai nguyen's answer

import React from 'react'
import { useTable, useSortBy } from 'react-table';

function Table({ columns, data, sortBy ...rest }) {
    const {
        getTableProps,
        getTableBodyProps,
        headerGroups,
        rows,
        prepareRow,
        setSortBy,
    } = useTable({
        columns,
        data,
        initialState: {sortBy}
        })
    }, useSortBy); 

Then in your column header element:

     ...PREV_TABLE_CODE
{headerGroup.headers.map(column => (
         <th
         {...column.getHeaderProps()}
         onClick={() => handleMultiSortBy(column, setSortBy, sortBy)}
          >
         {column.render( 
REST_TABLE_CODE....

and the handleMultiSortByCode (my custom function, not from react-table):

isSortedDesc can be either true/false/undefined

export const handleMultiSortBy = (column, setSortBy, meinSortBy) => {
  //set sort desc, aesc or none?
  const desc =
    column.isSortedDesc === true
      ? undefined
      : column.isSortedDesc === false
      ? true
      : false;
  setSortBy([{ id: column.id, desc }, ...meinSortBy]);
};
 

Note: The default toggleSortBy() func had a e.persist() in it. I'm not sure what function it served, but not using it doesn't have any ill effects that I've noticed - the stock multi-sort doesn't work (holding shift) but adding it back didn't fix that. Suspect you might need the stock toggleSort for that.

sirclesam
  • 2,109
  • 17
  • 13
3

You need to import the 'useSortBy' hook provided by react-table to make it work as expected.

import React from 'react'
import { useTable, useSortBy } from 'react-table';

function Table({ columns, data, ...rest }) {
    const {
        getTableProps,
        getTableBodyProps,
        headerGroups,
        rows,
        prepareRow,
    } = useTable({
        columns,
        data,
        ...(rest.initialState && {
            initialState: rest.initialState
        })
    }, useSortBy);
Faktor 10
  • 1,868
  • 2
  • 21
  • 29
1

In the case of sorting by default in React Table, there are a couple of issues to work/sort out. But unlike some other answers, you dont need to use local state or anything besides React Table hooks and props. This answers only your sorting question, not filtering:

disableSortRemove: true is a React Table prop; and adding it gets you to a place of, on the very first click you'll still have an "unsorted" state, and then subsequent clicks are sorted asc or desc, as opposed to the default behavior, which on a third click gets you back to an "unsorted" state. That's perhaps not the UI you want, as a button click, first or not, should do something, but with that one variable, on first click it wont.

You want two columns sorted by default, and only sort asc or desc, so you need a couple more elements in place. Here's what your setup may look like.

const { getTableProps, getTableBodyProps, headerGroups, rows, prepareRow } = useTable(
    {
      columns: tableColumns,
      data: tableData,
      disableSortRemove: true,
      defaultCanSort: true,
      initialState: {
        sortBy: [{ id: tableData[0]?.totalSeries?.series, desc: true }], // IMPORTANT: Use your own data structure and add as many columns that need sorting by default
      },
    },
    useSortBy
  );

Here we've added 3 things rather than just the one disableSortRemove: true. We've added:

disableSortRemove: true, defaultCanSort: true, and initialState: { sortBy: [{ id: tableData[0]?.totalSeries?.series, desc: true }] },

I don't think you need the second one (defaultCanSort: true) BUT the first and third give you the effect you want: On page load, sorting is on and once you click the sort button it sorts the opposite way. The two columns you add to the initialState array will be sorted by default.

Done. Sorted.

Cat Perry
  • 944
  • 1
  • 11
  • 15