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-tableuseSortBy 挂钩构建的。在我从 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)]);