React-table: Sorting not really working

Created on 9 Feb 2017  Â·  16Comments  Â·  Source: tannerlinsley/react-table

Yet another sorting issue..!

I need to sort my data according to only one column with IDs, so I have set the sort: 'asc', but sorting is not really well done. Clicking the column header changes the sorting but in a weird way, some rows are ordered, some are not.

I am also pivoting by 2 columns, but even when I don't, my data still is not shown in a sorted order. Also not working if I pivot by more columns. So pivoting is not the issue here I think.

The data that I provide are already in the order I want, so theoretically even if i disable all sorting options, they should be shown in the order I provide them, right? or is this not the expected behavior?

Most helpful comment

Ah I see the problem. You are using accessor to return the jsx you want to display. The accessor should be a key or function that returns the raw data for the column. If you want to customize the display of that value, you use render. Example for the kpiNumber column:

{
  header: 'NO',
  id: 'kpiNumber',
  accessor: 'kpiNumber', // or `row => row.kpiNumber` (same thing)
  aggregate: (values, rows) => <span>{values.length === 1 ? values[0] : ''}</span>,
  display: rowInfo => <span className='awesomeClass'>{rowInfo.value}</span>,
  width: 50,
  sort: 'asc'
}

Just remember that accessors are what build the data model for the table to sort. So whatever you return in your accessor should be a naturally sortable primitive (number, string, date, boolean).

Let me know if that fixes the problem for you (remember to check your accessor functions for the rest of your columns as well ;)

All 16 comments

Can you post a sample of your data and your column defs?
On Thu, Feb 9, 2017 at 8:46 AM Irene Pap notifications@github.com wrote:

Yet another sorting issue..!

I need to sort my data according to only one column with IDs, so I have
set the sort: 'asc', but sorting is not really well done. Clicking the
column header changes the sorting but in a weird way, some rows are
ordered, some are not.

I am also pivoting by 2 columns, but even when I don't, my data still is
not shown in a sorted order. Also not working if I pivot by more columns.
So pivoting is not the issue here I think.

The data that I provide are already in the order I want, so theoretically
even if i disable all sorting options, they should be shown in the order I
provide them, right? or is this not the expected behavior?

—
You are receiving this because you are subscribed to this thread.
Reply to this email directly, view it on GitHub
https://github.com/tannerlinsley/react-table/issues/72, or mute the
thread
https://github.com/notifications/unsubscribe-auth/AFUmCfjY_zDlI7a2weKFIffyV2bL8IBJks5razTTgaJpZM4L8SjI
.

Thank you for the quick response.

I am struggling with this all day, and only when I pasted my code here for this answer I realized my mapping of the values was wrong.

It works now, but only if I click 2 times on the column that needs to be sorted by default. First two clicks sorting is pretty random.

columns: [
      {
        header: 'Sections',
        columns: [{
          header: 'Section',
          accessor: 'sectionName',
          minWidth: 200,
          sortable: false
        }, {
          header: 'Sub-Section',
          accessor: 'subSectionName',
          sortable: false
        }]
      },
      {
        header: 'KPIs',
        columns: [{
          header: 'KPI',
          accessor: 'kpiName_1',
          minWidth: 200,
          aggregate: (values, rows) => <span>{values.length === 1 ? values[0] : ''}</span>,
          sortable: false
        }, {
          header: 'Sub-KPI',
          accessor: 'kpiName_2',
          minWidth: 140,
          sortable: false
        }, {
          header: 'Sub-Sub-KPI',
          accessor: 'kpiName_3',
          sortable: false
        }, {
          header: 'Really-Deep-KPI',
          accessor: 'kpiName_4',
          sortable: false
        }]
      },
      {
        header: 'Details',
        columns: [{
          header: 'Frequency',
          id: 'kpiFreq',
          accessor: data => <span>{data.kpiFreq_4 || data.kpiFreq_3 || data.kpiFreq_2 || data.kpiFreq_1}</span>,
          aggregate: (values, rows) => <span>{values.length === 1 ? values[0] : ''}</span>,
          sortable: false,
          minWidth: 80
        }, {
          header: 'Type',
          id: 'kpiType',
          accessor: data => <span>{data.kpiType_4 || data.kpiType_3 || data.kpiType_2 || data.kpiType_1}</span>,
          aggregate: (values, rows) => <span>{values.length === 1 ? values[0] : ''}</span>,
          sortable: false,
          minWidth: 60
        }, {
          header: 'NO',
          id: 'kpiNumber',
          accessor: data => <span>{data.kpiNumber}</span>,
          aggregate: (values, rows) => <span>{values.length === 1 ? values[0] : ''}</span>,
          width: 50,
          sort: 'asc'
        }]
      }]

// [...] month columns omitted 

Sample data:

data: [
   0: {
        piFreq_1: "MONTHLY",
        kpiId_1: "KPI_ID_A",
        kpiName_1: "KPI_A",
        kpiNumber: 1,
        kpiType_1: "SUM",
        months: Array[12], //omitted
        sectionName: "SECTION_A",
        subSectionName: "(no subsection)"
   },
   1: {
        kpiFreq_2: "MONTHLY",
        kpiId_2: "KPI_ID_B",
        kpiName_1: "KPI_A",
        kpiName_2: "KPI_B",
        kpiNumber: 2,
        kpiType_2: "UNITS",
        months: Array[12], //omitted
        sectionName: "SECTION_A",
        subSectionName: "(no subsection)"
   },
 2: {
        kpiFreq_2: "MONTHLY",
        kpiId_2: "KPI_ID_C",
        kpiName_1: "KPI_A",
        kpiName_2: "KPI_C",
        kpiNumber: 3,
        kpiType_2: "UNITS",
        months: Array[12], //omitted
        sectionName: "SECTION_A",
        subSectionName: "(no subsection)"
   },
]
// [...] more than 200 of these fellows

I want to sort on the KPI Number column.
Extra funny issue, if I write the accessor the string way: accessor: 'kpiNumber' then I have to click 5 times for the correct sorting order to appear.

Ah I see the problem. You are using accessor to return the jsx you want to display. The accessor should be a key or function that returns the raw data for the column. If you want to customize the display of that value, you use render. Example for the kpiNumber column:

{
  header: 'NO',
  id: 'kpiNumber',
  accessor: 'kpiNumber', // or `row => row.kpiNumber` (same thing)
  aggregate: (values, rows) => <span>{values.length === 1 ? values[0] : ''}</span>,
  display: rowInfo => <span className='awesomeClass'>{rowInfo.value}</span>,
  width: 50,
  sort: 'asc'
}

Just remember that accessors are what build the data model for the table to sort. So whatever you return in your accessor should be a naturally sortable primitive (number, string, date, boolean).

Let me know if that fixes the problem for you (remember to check your accessor functions for the rest of your columns as well ;)

Sadly this doesn't fix the problem. I cleaned up all my accessor functions. Now I have to indeed click 5 times until the correct sorting is shown.
I also have the common warning about a needed key value, don't know if this is related to my issue:

warning.js:36 Warning: Each child in an array or iterator should have a unique "key" prop. 
Check the render method of `src`. 
See https://fb.me/react-warning-keys for more information.
    in ThComponent (created by src)
   // [...]

Btw I guess you mean render in your code instead of 'display' :).

EDIT: If I don't pivot by no columns, then sorting is correct from the start! So pivoting messes with it somehow. I'm looking at it now and I will also check my aggregate functions. This is my <ReactTable> component config:

<ReactTable
          className="-highlight"
          data={data}
          columns={columns}
          defaultPageSize={numOfSections}
          showPagination={false}
          showPageJump={false}
          showPageSizeOptions={false}
          //pivotBy={['sectionName', 'subSectionName']}
          onTrClick={this.handleTrClick} //console.logs the row
        />

EDIT 2: Turns out pivoting messes with some styles as well. If I have trStyleCallback={ rowInfo => {return( {color: rowInfo.rowValues.sectionNumber % 2 ? 'green' : 'red'} )} } it works as expected only when the pivotBy prop is commented-out. Maybe I am doing something wrong with pivot/aggregation?

Upgrading to the newest version of react-table fixed my issue.
I am sorry that this was not the first step I took before even posting here, I hope I didn't waste much of your time!

Your good! Just glad it is working ;)
On Fri, Feb 10, 2017 at 6:40 AM Irene Pap notifications@github.com wrote:

Upgrading to the newest version of react-table fixed my issue.
I am sorry that this was not the first step I took before even posting
here, I hope I didn't waste much of your time!

—
You are receiving this because you commented.

Reply to this email directly, view it on GitHub
https://github.com/tannerlinsley/react-table/issues/72#issuecomment-278944040,
or mute the thread
https://github.com/notifications/unsubscribe-auth/AFUmCX-QW7nzHNZ0EiTxYSxuZM3zym1rks5rbGi7gaJpZM4L8SjI
.

Turns out I have to re-open this.

Behavior is that sorting is done within each group of pivoted columns, but the groups themselves are not sorted.

Say,
SectionA contains items with IDs 1 to 20. These items are internally sorted.
SectionB contains items with IDs 21 - 30. They are sorted.
SectionC contains items with IDs 30-60. Sorted.

I would like to see SectionA - SectionB - SectionC, but they appear like: SectionA - SectionC - SectionB.
If I expand them, the rows-items are sorted within their subsection.
I would like the priority to be on the overall sorting of the items, and not only per group of pivoted columns.

I have to click to the ID column [kpiNumber in my code] 5 times for the correct sorting to be applied.

Maybe the sorting is applied in code before the pivoting, that's the grouped columns have sorted data, but the groups are not themselves sorted.

I hope my explanation, even though not very clear, is at least helpful to point to the right direction into solving this..

Okay, I've verified that there was indeed a strange error happening. I've shipped a new version 5.1.0 that should fix the issue, but it did break some small things with the old column sorting shorthand.

Instead of setting sort: 'asc', use the new defaultSorting prop:

<ReactTable
  defaultSorting={[{
    id: 'kpiNumber',
    desc: false // not necessary unless set to true, but it's good to know its there.
}]}

As for your columns, make sure that accessors are returning primitives, and if you are using a function for an accessor that you set a unique ID.

Does that work for you?

It works!!
Actually, it works if I keep sort: 'asc' in the column definition. When I use the defaultSorting prop, it doesn't work [or well, it works as before, that is I need to click 3 times at the column to see the correct overall sorting].

Thank you very much for the fix, seems like it didn't break some small things after all [?].

Awesome. Just be sure to upgrade to the latest version. The inline column
sort key isn't used anymore, and the table will strictly use the
defaultSorting prop.

On Mon, Feb 13, 2017 at 1:58 AM Irene Pap notifications@github.com wrote:

It works!!
Actually, it works if I keep sort: 'asc' in the column definition. When I
use the defaultSorting prop, it doesn't work [or well, it works as
before, that is I need to click 3 times at the column to see the correct
overall sorting].

Thank you very much for the fix, seems like it didn't break some small
things after all [?].

—
You are receiving this because you commented.

Reply to this email directly, view it on GitHub
https://github.com/tannerlinsley/react-table/issues/72#issuecomment-279328388,
or mute the thread
https://github.com/notifications/unsubscribe-auth/AFUmCedhnLrUMZ5SvhQDJj9m95jV3HXHks5rcBtFgaJpZM4L8SjI
.

Hey,

I have defaultSorting as a prop for one of my columns and this works fine. But it seems I am unable to click on the same column to resort unless I click on a different column and then come back to the original column. Code seems fine, what could I be missing ?

Below is my column
{ id: 'dateCreated', header: 'Date Created', accessor: 'createdDate', render: row => { return ( <span> {dateFormat(row.value, 'mm/dd/yy HH:MM:ss')} </span> ) } },

This is the options for the table
return { minRows: 0, showPageSizeOptions: false, showPageJump: false, showPagination: false, theadClassName: 'ash-thead', className: '-striped -highlight ash-table', defaultPageSize: 100, defaultSorting: [{ id: 'dateCreated', asc: false }] }
Please advise, thank you.

Hi @tannerlinsley ,
I am using react-table version: 6.8.0, and i am facing similar issue mentioned above. When I am pivoting a column, react table is overriding the order of the data received from the server and it happens on some of the instance only.

if I remove prop pivoted by then it works just fine.

below how my table looks like:

<ReactTable
              data={productData}
              columns={columns(this)}
              defaultPageSize={DEFAULT_PAGE_SIZE}
              pageSizeOptions={PAGE_SIZE_OPTIONS}
              className="-striped -highlight"
              pivotBy={["id"]}
              sortable={true}
              filterable
              manual
              onFetchData={this.getProductList}
              pages={pages}
              loading={loading}
              noDataText={productError || (loading ? "" : "Sorry there are no results matching your criteria")}
              loadingText={<LoadingSpinner/>}
              PaginationComponent={ReactTablePagination}
              showPaginationTop={true}
              showPaginationBottom={true}
              showPageJump={false}
              sorted={tableState.sorted}
              page={tableState.page}
              pageSize={tableState.pageSize}
              expanded={tableState.expanded}
              resized={tableState.resized}
              filtered={tableState.filtered}
              onSortedChange={sortedChanged}
              onPageChange={pageChanged}
              onPageSizeChange={pageSizeChanged}
              onExpandedChange={expandedChanged}
              onResizedChange={resizedChanged}
              onFilteredChange={filteredChanged} />

Even i am some issue in react table, when I clicked on column I got data in sorted format but when it goes to next page some data from 1st page get displayed
means in page 1:column contain 1 to 10 values
in page 2:column contains 8 to 18 values ,why such repetition happen?

I would like to initially sort by distance {
id: 'distance',
Header: 'Distance',
accessor: d => {
return geodist({lat:this.state.geo.latitude, lon:this.state.geo.longitude},
{lat: d.coordinates.latitude, lon:d.coordinates.longitude}, {exact: true}).toFixed(2)
}
} is there a way to initially sort from an accessor that is a function?

I have used Sl.No as first column,so the data will be like 1,2,3... when i try to sort other columns, Sl.No column also will be sorted, is there any way to keep it static(maybe disable it permanently)???

Was this page helpful?
0 / 5 - 0 ratings

Related issues

mlajszczak picture mlajszczak  Â·  3Comments

LeonHex picture LeonHex  Â·  3Comments

panfiva picture panfiva  Â·  3Comments

dilipsundarraj1 picture dilipsundarraj1  Â·  3Comments

ocalde picture ocalde  Â·  3Comments