I am trying to sort data in a react-table, but as new data arrives the sorts are nullified. The component containing the table gets its data from a prop. That data itself comes from redux, which is updated every 15 seconds with the latest data from the server (where it is changing frequently).
What I'd like is to sort the data, and for those sorts to stay in place as/when the data changes. What actually happens is that I sort the table by a column header, and then when the data changes the sorts are removed.
I have tried:
- setting
autoResetSortByto false - implemented this: https://react-table.tanstack.com/docs/faq#how-do-i-stop-my-table-state-from-automatically-resetting-when-my-data-changes
- read through docs and examples looking for obvious differences
but becomes this as soon as data changes:

I would like to preserve the sort filter so that as new data arrives (the same 99% of the time, but 1% of the time a column value is different or there is a new row) it is sorted by the applied sort filter.
Here's a simplified example of my code (as small as I could make it):
import * as React from 'react'
import { useTable, Column, useSortBy } from 'react-table'
import * as SharedTypes from '@shared/declarations'
interface Props {
serverData: SharedTypes.API.MarketBotSummary[]
}
export const TableTest: React.StatelessComponent<Props> = ({ serverData }: Props) => {
const [localData, setLocalData] = React.useState<SharedTypes.API.MarketBotSummary[]>(serverData)
const skipPageResetRef = React.useRef<boolean>(false)
React.useEffect(() => {
skipPageResetRef.current = true
setLocalData(serverData)
console.log('data changed', serverData)
}, [serverData])
React.useEffect(() => {
// After the table has updated, always remove the flag
skipPageResetRef.current = false
})
const Table = ({ columns, data }: { columns: Column<SharedTypes.API.MarketBotSummary>[], data: SharedTypes.API.MarketBotSummary[]}) => {
// Use the state and functions returned from useTable to build your UI
const {
getTableProps,
getTableBodyProps,
headerGroups,
rows,
prepareRow,
// @ts-ignore
state: { sortBy }
} = useTable(
{
columns,
data,
// @ts-ignore
// autoResetSortBy: false,
// autoResetFilters: false,
autoResetPage: !skipPageResetRef.current,
autoResetExpanded: !skipPageResetRef.current,
autoResetGroupBy: !skipPageResetRef.current,
autoResetSelectedRows: !skipPageResetRef.current,
autoResetSortBy: !skipPageResetRef.current,
autoResetFilters: !skipPageResetRef.current,
autoResetRowState: !skipPageResetRef.current,
},
useSortBy
)
// Render the UI for your table
return (
<>
<table {...getTableProps()} className="ui celled very compact structured table">
<thead>
{
// @ts-ignore
headerGroups.map(headerGroup => (
<tr {...headerGroup.getHeaderGroupProps()}>
{
// @ts-ignore
headerGroup.headers.map(column => (
<th {
// @ts-ignore
...column.getHeaderProps(column.getSortByToggleProps())
}>
{column.render('Header')}
<span>
{
// @ts-ignore
column.isSorted ? column.isSortedDesc ? ' ' : ' ' : ''
}
</span>
</th>
))}
</tr>
))}
</thead>
<tbody {...getTableBodyProps()}>
{
// @ts-ignore
rows.map((row) => {
prepareRow(row)
return (
<tr {...row.getRowProps()}>
{row.cells.map(
// @ts-ignore
cell => <td {...cell.getCellProps({ className: cell.column?.className?.(cell.value, row.original) })}>
{cell.render('Cell')}
</td>
)}
</tr>
)
})}
</tbody>
</table>
<pre>
<code>
{JSON.stringify(
{
sortBy,
},
null,
2
)}
</code>
</pre>
</>
)
}
const columns = React.useMemo(
() => [
{
Header: 'Data',
columns: [
{
Header: 'Quote',
accessor: 'quote',
},
{
Header: 'Symbol',
accessor: 'symbol',
},
{
Header: 'Mode',
accessor: 'status',
},
{
Header: 'direction',
accessor: 'tradeDirection',
},
],
},
],
[]
)
const data = React.useMemo(
() => localData,
[localData]
)
return (
<Table columns={columns} data={data} />
)
}
export default TableTest
