React-Table中自定义单元格的列无法进行排序

8

我正在使用 react-table 插件,并且在为一个自定义链接定义的一列使排序工作时遇到了困难。

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

我很确定问题出在 columns 定义中,但为了完整起见,我将在此处发布所有代码:

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表头时的示例;它确实进行了排序,但似乎将行分成了两组:

enter image description here

我认为问题可能是链接定义有误,可能会影响标签的排序,但当我将其更改为:

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

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

你可能需要使用 sortMethod 自己定义排序方法,就像这个例子中的方式:https://codesandbox.io/s/l776y47n9?file=/index.js - Mosh Feu
顺便提一下,“唯一标识符”是针对每个列的,你可以只写类似于 id: "name" 这样的内容,不需要生成唯一的字符串。 - szaman
2个回答

3

当我将列中的accessor属性留空时,它就奏效了:

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

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

2

在我的看来,这个问题似乎没什么问题。如果你看快照,第一个排序集合有大写字母开头的单词,而第二个集合则是小写字母,这意味着默认排序似乎区分大小写。

你需要使用自定义排序或其他可用的排序方法来进行不区分大小写的排序。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接