如何使用React Query对获取的数据进行排序?
实现React Query数据的表格排序功能
你需要将排序状态管理、排序逻辑与表头交互结合,同时适配你的数据结构(如checkout_step_1这类数组型字段),以下是完整修改方案:
核心修改步骤
- 恢复排序状态变量:启用注释掉的
sortField和order状态,用于跟踪当前排序字段与顺序 - 适配数据结构调整排序函数:你的排序目标字段(如
checkout_step_1)是数组,需取数组第一个元素(数值部分)进行比较,同时基于React Query返回的response.data处理排序 - 添加表头点击交互:给需要支持排序的表头添加点击事件,触发排序逻辑
- 渲染排序后的数据:根据当前排序状态处理原始数据,渲染排序后的结果
修改后的完整代码
import React, { useState, useMemo } from "react"; import useFetchTable from "../../../../api/table/useFetchTable"; const TableList = () => { const { data: response, status, isLoading } = useFetchTable(); const [sortField, setSortField] = useState(""); const [order, setOrder] = useState("asc"); const handleSortingChange = (accessor) => { const sortOrder = accessor === sortField && order === "desc" ? "asc" : "desc"; setSortField(accessor); setOrder(sortOrder); }; // 用useMemo优化,仅在依赖变化时重新排序 const sortedData = useMemo(() => { if (!response?.data || !sortField) return response?.data; return [...response.data].sort((a, b) => { // 针对数组型字段,取第一个元素作为排序值 const valA = a[sortField]?.[0] ?? null; const valB = b[sortField]?.[0] ?? null; if (valA === null) return 1; if (valB === null) return -1; if (valA === null && valB === null) return 0; return valA.toString().localeCompare(valB.toString(), "en", { numeric: true, }) * (order === "asc" ? 1 : -1); }); }, [response?.data, sortField, order]); if (status === "error") { return "Error"; } if (isLoading) { return "Loading..."; } const Print = ({ children }) => { return ( <span className="text-xs bg-blue-100 rounded-full px-2 py-0.5 ml-2"> {children}% </span> ); }; return ( <div> <table> <thead className="border-b-2"> <tr> <th className="py-1">Product Name</th> <th>Purchases</th> <th>US</th> {/* 给表头添加点击事件,传入对应的字段名 */} <th onClick={() => handleSortingChange("checkout_step_1")} style={{cursor: 'pointer'}}>Ch Step 1</th> <th onClick={() => handleSortingChange("checkout_step_2")} style={{cursor: 'pointer'}}>Ch Step 2</th> <th>CVR</th> <th onClick={() => handleSortingChange("upsell_1_takes")} style={{cursor: 'pointer'}}>Upsell 1</th> <th onClick={() => handleSortingChange("upsell_2_takes")} style={{cursor: 'pointer'}}>Upsell 2</th> <th onClick={() => handleSortingChange("upsell_3_takes")} style={{cursor: 'pointer'}}>Upsell 3</th> </tr> </thead> <tbody> {/* 渲染排序后的sortedData */} {sortedData?.map((row, idx) => ( <tr key={idx}> <td>{row.name}</td> <td> {row.purchases[0]} <Print>{row.purchases[1]}</Print> </td> <td> {row.unique_sessions} <Print>100</Print> </td> <td> {row.checkout_step_1[0]} <Print>{row.checkout_step_1[1]}</Print> </td> <td> {row.checkout_step_2[0]} <Print>{row.checkout_step_2[1]}</Print> </td> <td> <Print>{`${row["cvr_%"]}`}</Print> </td> <td> {row.upsell_1_takes[0]} <Print>{row.upsell_1_takes[1]}</Print> </td> <td> {row.upsell_2_takes[0]} <Print>{row.upsell_2_takes[1]}</Print> </td> <td> {row.upsell_3_takes[0]} <Print>{row.upsell_3_takes[1]}</Print> </td> </tr> ))} </tbody> </table> TableList </div> ); }; export default TableList;
关键说明
- useMemo优化:将排序逻辑包裹在
useMemo中,仅当response.data、sortField或order变化时才重新计算排序结果,避免不必要的性能损耗 - 数组字段处理:排序时取数组的第一个元素(
valA = a[sortField]?.[0] ?? null),适配你数据中类似checkout_step_1的数组结构 - 表头交互:给可排序的表头添加点击事件,传入对应的字段名(如
checkout_step_1),点击时切换排序顺序 - 状态驱动渲染:通过
sortedData变量统一管理排序后的数据,渲染时直接使用该变量即可
内容的提问来源于stack exchange,提问作者user16073989
相关产品推荐
相关产品推荐

