如何使用SWR结合对象形式的搜索条件实现分页?
使用SWR结合POST请求实现带复杂搜索条件的分页
当然可以实现。SWR允许将数组作为请求key传递多组参数,同时我们可以把分页参数和复杂搜索条件放入POST请求体中,避免URL过长的问题。以下是具体实现方案:
1. 修改Fetcher函数,支持POST请求
将原GET请求的fetcher改为接收请求地址和参数对象,通过POST方式把参数放入请求体:
const fetcher = async (url, params) => { const res = await fetch(url, { method: 'POST', headers: { 'Content-Type': 'application/json', }, body: JSON.stringify(params), }); if (!res.ok) throw new Error('数据请求失败'); return res.json(); };
2. 预处理搜索条件(序列化非字符串类型)
由于SWR会根据key的内容做缓存,日期等引用类型需要转为可序列化的字符串,避免不必要的重复请求:
// 处理搜索条件,将日期转为ISO标准字符串 const processedSearchCriteria = { ...searchCriteria, startDate: searchCriteria.startDate.toISOString(), endDate: searchCriteria.endDate.toISOString(), };
3. 结合SWR发起请求
将请求地址、分页参数、预处理后的搜索条件组成数组作为SWR的key,任何参数变化时SWR都会自动重新请求:
const { data, error, isLoading } = useSWR( ['/api/pager', { page: pageIndex, size: pageSize, ...processedSearchCriteria }], fetcher );
4. API后端接收参数示例(Express)
后端需要从POST请求体中获取参数,进行数据查询:
// Express 后端示例 app.post('/api/pager', async (req, res) => { const { page, size, description, startDate, endDate, submitted } = req.body; // 构建数据库查询条件(以MongoDB为例) const query = { description: { $regex: description, $options: 'i' }, createdAt: { $gte: new Date(startDate), $lte: new Date(endDate) }, submitted, }; // 执行分页查询 const total = await YourModel.countDocuments(query); const list = await YourModel.find(query) .limit(size) .skip((page - 1) * size); res.json({ list, total, page, size }); });
注意事项
- SWR的key数组中所有元素必须是可序列化类型(字符串、数字、普通对象),避免传入函数、Symbol等不可序列化值,否则会破坏缓存逻辑。
- 如果需要支持链接分享场景,可以考虑将复杂条件哈希后放入URL参数,但POST方式仍是复杂搜索场景的更优选择。
- 可根据业务需求配置SWR的缓存策略,比如
revalidateOnFocus、staleWhileRevalidate等选项。
内容的提问来源于stack exchange,提问作者Henry Fung
相关产品推荐
相关产品推荐

