求助:编写适配React-admin的Node.js分页、筛选、排序API
适配React-admin的Node.js API:搞定筛选、分页、排序
先对齐React-admin的传参规则
前端数据提供者会固定传递以下参数到后端,先匹配格式是核心前提:
- 分页:
page(起始页为1)、perPage(每页数据条数) - 排序:
sort(排序字段名)、order(排序方向,可选ASC/DESC) - 筛选:
filter(JSON格式字符串,例如{"title":"demo","status":"published"})
后端实现示例(以Express+Mongoose为例)
1. 解析请求参数
直接从req.query提取参数,注意类型转换和默认值设置:
app.get('/api/posts', async (req, res) => { // 分页参数处理 const page = parseInt(req.query.page) || 1; const perPage = parseInt(req.query.perPage) || 10; const offset = (page - 1) * perPage; // 转换为数据库可用的偏移量 // 排序参数处理 const sortField = req.query.sort || 'createdAt'; const sortOrder = req.query.order === 'DESC' ? -1 : 1; // 筛选参数处理:将JSON字符串转为对象 const filter = req.query.filter ? JSON.parse(req.query.filter) : {}; });
2. 适配数据库查询
把解析后的参数转为MongoDB可识别的查询语句:
// 构建筛选条件 const query = {}; // 标题模糊匹配(不区分大小写) if (filter.title) { query.title = { $regex: filter.title, $options: 'i' }; } // 状态精确匹配 if (filter.status) { query.status = filter.status; } // 执行分页+排序查询 const total = await Post.countDocuments(query); const posts = await Post.find(query) .sort({ [sortField]: sortOrder }) .skip(offset) .limit(perPage); // 返回React-admin要求的固定格式 res.json({ data: posts, total: total });
3. 验证自定义数据提供者
确保getList方法正确传递所有参数,避免遗漏:
const dataProvider = { getList: (resource, params) => { const { page, perPage } = params.pagination; const { field: sortField, order } = params.sort; const filterStr = JSON.stringify(params.filter); const url = `${process.env.API_URL}/${resource}?page=${page}&perPage=${perPage}&sort=${sortField}&order=${order}&filter=${filterStr}`; return fetch(url, { headers: { 'Content-Type': 'application/json', // 你的认证请求头 } }) .then(res => res.json()) .then(({ data, total }) => ({ data, total })); } };
常见问题排查
- 分页偏移量计算错误:React-admin的
page从1开始,必须转换为(page-1)*perPage,别直接用page*perPage - 筛选参数未解析:前端传递的
filter是JSON字符串,后端必须用JSON.parse转为对象,否则无法生成正确查询条件 - 返回格式不符合要求:必须包含
total字段,否则React-admin无法渲染分页组件 - 排序字段不匹配:后端数据库的字段名要和前端传递的
sort字段完全一致,比如前端传createdAt,后端不能写成create_time
内容的提问来源于stack exchange,提问作者Mansoor Saleem
相关产品推荐
相关产品推荐

