React-table:如何根据更改的单元格值对 table 数据进行排序(使用单元格 props.value 覆盖默认排序)?
React-table: How to sort table data based on the changed cell value (override the default sorting with cell props.value)?
背景
我有一个 table 使用 react-table
和 useSortBy
挂钩构建的。在我从 columns
更改 Cell
return 之前,一切正常。问题是,对于某些列,我必须修改数据在 table 上的显示方式(不改变数据本身)。例如,我在 table 上有一列不只显示原始数据,它必须将其他值组合到该数据,然后显示结果。看看下面的示例代码。
示例代码
import { useContext, useMemo } from "react";
import "../assets/css/result.css";
import { useTable, useSortBy } from "react-table";
import globalContext from "../globalContext/globalData";
const Result = () => {
const { searchResults } = useContext(globalContext);
const columns = useMemo(() => headers, []); // headers defined below
const data = useMemo(() => searchResults, [searchResults]);
return (
<section id="result">
<div className="title">
<p>Here is my fancy table</p>
</div>
<div className="table">
<Table columns={columns} data={data} />
</div>
</section>
);
};
export default Result;
function Table({ columns, data }) {
const { getTableProps, getTableBodyProps, headerGroups, rows, prepareRow } = useTable(
{
columns,
data,
},
useSortBy
);
return (
<table {...getTableProps()}>
<thead>
{headerGroups.map(headerGroup => (
<tr {...headerGroup.getHeaderGroupProps()}>
{headerGroup.headers.map(column => (
// Add the sorting props to control sorting. For this example
// we can add them into the header props
<th {...column.getHeaderProps(column.getSortByToggleProps())}>
{column.render("Header")}
{/* Add a sort direction indicator */}
<span>{column.isSorted ? (column.isSortedDesc ? "⇩" : "⇧") : ""}</span>
</th>
))}
</tr>
))}
</thead>
<tbody {...getTableBodyProps()}>
{rows.map((row, i) => {
prepareRow(row);
return (
<tr {...row.getRowProps()}>
{row.cells.map(cell => {
return (
<td {...cell.getCellProps({ className: cell.column.className })}>
{cell.render("Cell")}
</td>
);
})}
</tr>
);
})}
</tbody>
</table>
);
}
const headers = [
{
Header: "Normal Column",
accessor: "normal_column",
// Cell: props => props.value, // default behaviour
},
{
Header: "Order count",
accessor: "order_count",
Cell: props => `${Number(props.value).toLocaleString("en")} 個`, // 5510 => 5,510 個
// here sorting works fine as the cell display value hasnt changed much
},
{
Header: "Other Column",
accessor: "column_name",
// BUG: sorting does not work properly as it still uses props.value
Cell: props => {
// Here I have to display the value in a different way, combining somethings from the original row data
// displays as expected, but the sorting is still done based on the default props.value under the hood
const { var1, var2, var3 } = props.row.original;
return `${var1}-${var2}-${var3}`; // this should be what sorting is based on, not props.value
},
},
];
问题
假设我将单元格显示值从原来的 5510
更改为 5,510 個
(用逗号将数字格式化为千位分隔符并在末尾放置 space+个)。排序效果很好,因为 5,510 个和 5510 个值的排序结果相差不大。
这是它变得棘手的时候:我需要一个新列,它组合两个或三个行值并输出特定显示值,如示例代码的 headers
对象内所示。现在排序无法按预期进行(基于 Cell 的 return 值)。
我试过的
我尝试在我的 headers
对象中覆盖 props.value
from Cell
函数。但它是immutable。所以这没有用。我应该如何解决这个问题?我错过了什么?
在将 props 传递给 Table 组件之前,与其尝试在 Cell 函数中设置显示值,不如这样做,这是我在不更改原始内容的情况下能想到的唯一方法来自 react table 钩子的排序函数,因为它希望直接使用您在开头提供的 props.value 进行排序。
也许是这样的:
const formatMyData = (searchResults)=>{
return searchResults.map((result)=>({...result, myFormattedColumn: `${result.data1}-${result.data2}-${result.data3}`}))
}
const data = useMemo(() => searchResults, [formatMyData(searchResults)]);
背景
我有一个 table 使用 react-table
和 useSortBy
挂钩构建的。在我从 columns
更改 Cell
return 之前,一切正常。问题是,对于某些列,我必须修改数据在 table 上的显示方式(不改变数据本身)。例如,我在 table 上有一列不只显示原始数据,它必须将其他值组合到该数据,然后显示结果。看看下面的示例代码。
示例代码
import { useContext, useMemo } from "react";
import "../assets/css/result.css";
import { useTable, useSortBy } from "react-table";
import globalContext from "../globalContext/globalData";
const Result = () => {
const { searchResults } = useContext(globalContext);
const columns = useMemo(() => headers, []); // headers defined below
const data = useMemo(() => searchResults, [searchResults]);
return (
<section id="result">
<div className="title">
<p>Here is my fancy table</p>
</div>
<div className="table">
<Table columns={columns} data={data} />
</div>
</section>
);
};
export default Result;
function Table({ columns, data }) {
const { getTableProps, getTableBodyProps, headerGroups, rows, prepareRow } = useTable(
{
columns,
data,
},
useSortBy
);
return (
<table {...getTableProps()}>
<thead>
{headerGroups.map(headerGroup => (
<tr {...headerGroup.getHeaderGroupProps()}>
{headerGroup.headers.map(column => (
// Add the sorting props to control sorting. For this example
// we can add them into the header props
<th {...column.getHeaderProps(column.getSortByToggleProps())}>
{column.render("Header")}
{/* Add a sort direction indicator */}
<span>{column.isSorted ? (column.isSortedDesc ? "⇩" : "⇧") : ""}</span>
</th>
))}
</tr>
))}
</thead>
<tbody {...getTableBodyProps()}>
{rows.map((row, i) => {
prepareRow(row);
return (
<tr {...row.getRowProps()}>
{row.cells.map(cell => {
return (
<td {...cell.getCellProps({ className: cell.column.className })}>
{cell.render("Cell")}
</td>
);
})}
</tr>
);
})}
</tbody>
</table>
);
}
const headers = [
{
Header: "Normal Column",
accessor: "normal_column",
// Cell: props => props.value, // default behaviour
},
{
Header: "Order count",
accessor: "order_count",
Cell: props => `${Number(props.value).toLocaleString("en")} 個`, // 5510 => 5,510 個
// here sorting works fine as the cell display value hasnt changed much
},
{
Header: "Other Column",
accessor: "column_name",
// BUG: sorting does not work properly as it still uses props.value
Cell: props => {
// Here I have to display the value in a different way, combining somethings from the original row data
// displays as expected, but the sorting is still done based on the default props.value under the hood
const { var1, var2, var3 } = props.row.original;
return `${var1}-${var2}-${var3}`; // this should be what sorting is based on, not props.value
},
},
];
问题
假设我将单元格显示值从原来的 5510
更改为 5,510 個
(用逗号将数字格式化为千位分隔符并在末尾放置 space+个)。排序效果很好,因为 5,510 个和 5510 个值的排序结果相差不大。
这是它变得棘手的时候:我需要一个新列,它组合两个或三个行值并输出特定显示值,如示例代码的 headers
对象内所示。现在排序无法按预期进行(基于 Cell 的 return 值)。
我试过的
我尝试在我的 headers
对象中覆盖 props.value
from Cell
函数。但它是immutable。所以这没有用。我应该如何解决这个问题?我错过了什么?
在将 props 传递给 Table 组件之前,与其尝试在 Cell 函数中设置显示值,不如这样做,这是我在不更改原始内容的情况下能想到的唯一方法来自 react table 钩子的排序函数,因为它希望直接使用您在开头提供的 props.value 进行排序。
也许是这样的:
const formatMyData = (searchResults)=>{
return searchResults.map((result)=>({...result, myFormattedColumn: `${result.data1}-${result.data2}-${result.data3}`}))
}
const data = useMemo(() => searchResults, [formatMyData(searchResults)]);