react如何封装usetable
封装 useTable Hook 的方法
在 React 中封装 useTable Hook 可以简化表格组件的逻辑,提高代码复用性。以下是几种常见的封装方法:
基础封装
创建一个自定义 Hook,接收表格数据、列配置和分页参数,返回表格渲染所需的属性和方法。
import { useState } from 'react';
function useTable(data, columns, initialPageSize = 10) {
const [pageIndex, setPageIndex] = useState(0);
const [pageSize, setPageSize] = useState(initialPageSize);
const paginatedData = data.slice(
pageIndex * pageSize,
(pageIndex + 1) * pageSize
);
return {
tableProps: {
data: paginatedData,
columns,
},
paginationProps: {
pageIndex,
pageSize,
total: data.length,
setPageIndex,
setPageSize,
},
};
}
支持排序
扩展 Hook 以支持列排序功能。
function useTable(data, columns) {
const [sortConfig, setSortConfig] = useState({ key: null, direction: 'asc' });
const sortedData = [...data].sort((a, b) => {
if (!sortConfig.key) return 0;
if (a[sortConfig.key] < b[sortConfig.key]) {
return sortConfig.direction === 'asc' ? -1 : 1;
}
if (a[sortConfig.key] > b[sortConfig.key]) {
return sortConfig.direction === 'asc' ? 1 : -1;
}
return 0;
});
const requestSort = key => {
setSortConfig(prev => ({
key,
direction: prev.key === key && prev.direction === 'asc' ? 'desc' : 'asc',
}));
};
return {
data: sortedData,
columns,
sortConfig,
requestSort,
};
}
集成 react-table
对于复杂表格需求,可以基于 react-table 库进行封装。
import { useTable } from 'react-table';
function useCustomTable({ columns, data, initialState = {} }) {
const instance = useTable({
columns,
data,
initialState,
});
return {
...instance,
// 添加自定义方法或状态
};
}
完整示例
结合分页、排序和过滤功能的完整封装示例。
import { useState, useMemo } from 'react';
function useTable(data, columns, options = {}) {
const { initialPageSize = 10, initialSort } = options;
const [pageIndex, setPageIndex] = useState(0);
const [pageSize, setPageSize] = useState(initialPageSize);
const [sortConfig, setSortConfig] = useState(initialSort);
const [filter, setFilter] = useState('');
const filteredData = useMemo(() => {
if (!filter) return data;
return data.filter(item =>
columns.some(col =>
String(item[col.accessor]).toLowerCase().includes(filter.toLowerCase())
)
);
}, [data, filter, columns]);
const sortedData = useMemo(() => {
if (!sortConfig) return filteredData;
return [...filteredData].sort((a, b) => {
if (a[sortConfig.key] < b[sortConfig.key]) {
return sortConfig.direction === 'asc' ? -1 : 1;
}
if (a[sortConfig.key] > b[sortConfig.key]) {
return sortConfig.direction === 'asc' ? 1 : -1;
}
return 0;
});
}, [filteredData, sortConfig]);
const paginatedData = useMemo(() => {
return sortedData.slice(pageIndex * pageSize, (pageIndex + 1) * pageSize);
}, [sortedData, pageIndex, pageSize]);
return {
tableProps: {
data: paginatedData,
columns,
sortConfig,
},
paginationProps: {
pageIndex,
pageSize,
total: sortedData.length,
setPageIndex,
setPageSize,
},
sortProps: {
setSortConfig,
},
filterProps: {
filter,
setFilter,
},
};
}
使用注意事项
- 性能优化:对于大数据集,使用
useMemo缓存计算结果 - 类型安全:使用 TypeScript 可以增强类型检查
- 可扩展性:预留扩展点以支持未来需求变更
- 测试覆盖:确保核心逻辑有充分的单元测试
以上封装方法可以根据实际项目需求进行调整和扩展。







