S..*_*S.. 9 reactjs redux react-table react-hooks
我正在尝试对反应表中的数据进行排序,但是随着新数据的到达,排序将被取消。包含表的组件从 prop 获取其数据。该数据本身来自 redux,它每 15 秒更新一次来自服务器(经常更改)的最新数据。
我想要的是对数据进行排序,并让这些排序在数据更改时保持不变。实际发生的情况是,我按列标题对表进行排序,然后当数据更改时,排序将被删除。
我努力了:
autoResetSortBy为假我想保留排序过滤器,以便当新数据到达时(99% 的时间相同,但 1% 的时间列值不同或存在新行),它会按应用的排序过滤器进行排序。
这是我的代码的简化示例(尽可能小):
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
Run Code Online (Sandbox Code Playgroud)
不要在其他 React 组件中声明 React 组件。每次 React 功能组件重新渲染时,它都会重新创建在其函数体中声明的所有内容,同时保留对来自各种钩子等的记忆useState变量useCallback的useMemo引用
当您在另一个组件的主体内声明一个组件时,您将在每次渲染时获得一个新组件,该组件不会保留先前渲染中的任何内部状态。因此,您的 UI 选择将被删除。
Table在单独的文件中声明并将其导入到TableTest. 或者,只需将所有内容移至Table的主体中即可TableTest。
我也会摆脱你的两个useMemo钩子,因为它们没有实现任何目标。在第一种情况下,如果您有一个静态数组/对象,只需在组件范围之外声明它,而在第二种情况下,localData状态钩子已经有效地记住了它。
| 归档时间: |
|
| 查看次数: |
9867 次 |
| 最近记录: |