react-table 排序不适用于带有自定义单元格的列

react-table sorting not working for column with custom cell

我正在使用 react-table 插件,但我很难对定义了自定义 link 的一列进行排序。

此列的内容基于该行数据的某些属性,因此我为其创建了一个自定义单元格。显示正常,但是排序很奇怪

我很确定问题出在 columns 定义中,但为了完整起见,我将 post 所有代码放在这里:

export default function CloudfrontList() {
    const [loading, setLoading] = useState(true);
    const [columns, setColumns] = useState([]);
    const [data, setData] = useState([]);

    const getDataForTable = async () => {
        const _columns = [{
            // This is the cell that doesn't sort properly
            Header: "Name",
            Cell: cell => {
                const row = cell.row.original;
                const value = row.comment ? row.comment : row.origins[0].domain_name;
                return (
                    <Link href="/view/cloudfront/[id]" as={`/view/cloudfront/${row.id}`}>
                        <a>{value}</a>
                    </Link>
                );
            },
            accessor: row => {
                return row.comment ? row.comment : row.origins[0].domain_name;
            },
            id: Math.random() // It needs a unique ID, right?
        }, {
            Header: "Identifier",
            accessor: "id"
        }, {
            Header: "Product",
            accessor: "tags.Product"
        }];

        const _assets = await readAllAssetsOfType(AssetType.Cloudfront);

        setColumns(_columns);
        setData(_assets);
        setLoading(false);
    };

    useEffect(() => {
        getDataForTable();
    }, []);

    return (
        <>
            <Head>
                <title>Cloudfront List :: {siteTitle}</title>
            </Head>

            {loading ? (
                "loading..."
            ) : (
                <Card>
                    <CardHeader>
                        All Cloudfront Assets
                        <Badge color="secondary" className="ml-2">{data.length}</Badge>
                    </CardHeader>
                    <CardBody>
                        <Table columns={columns} data={data} />
                    </CardBody>
                </Card>
            )}
        </>
    );
}


function Table({ columns, data }) {
    const {
        getTableProps,
        getTableBodyProps,
        headerGroups,
        rows,
        prepareRow,
    } = useTable(
        {
            columns,
            data
        },
        useSortBy
    );

    return (
        <>
            <table {...getTableProps()} className="table table-sm table-hover">
                <thead>
                    {headerGroups.map(headerGroup => (
                        <tr {...headerGroup.getHeaderGroupProps()}>
                            {headerGroup.headers.map(column => (
                                <th {...column.getHeaderProps(column.getSortByToggleProps())}>
                                    {column.render("Header")}
                                    <span>
                                        {column.isSorted
                                            ? column.isSortedDesc
                                                ? <FontAwesomeIcon icon={faSortDown} style={{ color: "#969696", width: "0.5rem" }} />
                                                : <FontAwesomeIcon icon={faSortUp} style={{ color: "#969696", width: "0.5rem" }} />
                                            : (
                                                <FontAwesomeIcon icon={faSort} style={{ color: "#969696", width: "0.5rem" }} />
                                            )}
                                    </span>
                                </th>
                            ))}
                        </tr>
                    ))}
                </thead>
                <tbody {...getTableBodyProps()}>
                    {rows.map(
                        row => {
                            prepareRow(row);
                            return (
                                <tr {...row.getRowProps()}>
                                    {row.cells.map(cell => {
                                        return (
                                            <td {...cell.getCellProps()}>{cell.render("Cell")}</td>
                                        );
                                    })}
                                </tr>
                            );
                        }
                    )}
                </tbody>
            </table>
        </>
    );
}

这是我单击 Name header 时发生的情况的示例;它确实进行了排序,但似乎将行分为两组:

我认为问题可能出在 link 定义上 - 它可能一直在对标签进行排序 - 但当我将其更改为:

Cell: cell => {
   const row = cell.row.original;
   const value = row.comment ? row.comment : row.origins[0].domain_name;
   return (
      value
   );
},

...问题仍然存在。有人可以指出我哪里错了吗?

这对我来说似乎很好,如果你在快照中看到,第一个排序集的第一个字母是大写的,第二个排序集的首字母是小写的,这意味着默认排序似乎是 case-sensitive。

您将需要使用自定义排序或任何其他排序方法(如果可用)进行不区分大小写的排序。

它对我有用,将列中的 accessor 属性 留空:

const columns: Column[] = [
  {
    Header: 'Name',
    Cell: (data: Cell) => {
      const original: any = data.row.original;

      return 'Something';
    },
    accessor: '',
  }
]