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: '',
}
]
我正在使用 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: '',
}
]