You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用RTK Query实现搜索与筛选功能?

基于RTK Query的搜索筛选最优实现方案

你的初始方案是否可行?

完全可行。把缓存数据存入本地状态(比如React的useState),筛选时更新状态变量展示结果、取消筛选时重置为原始缓存数据,这种方式逻辑简单,适合小型数据集场景。但缺点是需要手动同步缓存更新——如果RTK Query的缓存因重新请求、失效等原因更新,你得手动把新数据同步到本地状态,否则会出现展示数据和缓存不一致的问题。

基于RTK Query的更优实现方式

推荐直接在组件中基于RTK Query返回的原始缓存数据做实时筛选,无需额外维护本地状态,利用RTK Query的缓存特性自动同步数据更新:

1. 基础实时筛选实现

用useQuery获取原始数据,结合本地搜索状态(比如useState存搜索关键词),在渲染阶段直接对原始数据进行筛选:

import { useGetItemsQuery } from './apiSlice';
import { useState } from 'react';

function ItemList() {
  const [searchTerm, setSearchTerm] = useState('');
  const { data: allItems = [], isLoading } = useGetItemsQuery();

  // 实时生成筛选结果
  const filteredItems = allItems.filter(item => 
    item.name.toLowerCase().includes(searchTerm.toLowerCase())
  );

  if (isLoading) return <div>加载中...</div>;

  return (
    <>
      <input 
        type="text" 
        value={searchTerm} 
        onChange={(e) => setSearchTerm(e.target.value)}
        placeholder="搜索物品..."
      />
      <button onClick={() => setSearchTerm('')}>取消筛选</button>
      <ul>
        {filteredItems.map(item => (
          <li key={item.id}>{item.name}</li>
        ))}
      </ul>
    </>
  );
}

这种方式的优势:

  • 无需手动同步缓存,RTK Query缓存更新时,allItems会自动刷新,筛选结果也会实时同步
  • 代码简洁,减少状态维护成本
  • 适配大多数中小型数据集场景

2. 大型数据集优化:用RTK Query的select选项

如果数据集很大,每次渲染都执行filter会有性能开销,可以利用useQuery的select选项,让RTK Query在缓存层完成筛选,只返回符合条件的结果:

import { useGetItemsQuery } from './apiSlice';
import { useState, useMemo } from 'react';

function ItemList() {
  const [searchTerm, setSearchTerm] = useState('');
  
  // 用useMemo缓存筛选函数,避免不必要的缓存重新计算
  const selectFilteredItems = useMemo(() => {
    return (data) => {
      if (!searchTerm) return data;
      return data.filter(item => 
        item.name.toLowerCase().includes(searchTerm.toLowerCase())
      );
    };
  }, [searchTerm]);

  const { data: filteredItems = [], isLoading } = useGetItemsQuery(
    undefined, // 若你的query无需参数,此处传undefined
    { select: selectFilteredItems }
  );

  if (isLoading) return <div>加载中...</div>;

  return (
    <>
      <input 
        type="text" 
        value={searchTerm} 
        onChange={(e) => setSearchTerm(e.target.value)}
        placeholder="搜索物品..."
      />
      <button onClick={() => setSearchTerm('')}>取消筛选</button>
      <ul>
        {filteredItems.map(item => (
          <li key={item.id}>{item.name}</li>
        ))}
      </ul>
    </>
  );
}

select选项的作用是对RTK Query返回的缓存数据做转换后再传给组件,好处是:

  • 筛选逻辑在RTK Query内部处理,组件只需关注最终结果
  • 配合useMemo缓存select函数,避免每次搜索词变化触发不必要的缓存计算

3. 多条件筛选扩展

如果需要多条件筛选(比如按类别、价格范围),只需扩展本地状态和筛选逻辑即可,无论是基础方式还是select方式都能轻松适配:

// 多条件筛选示例(基础方式)
const [filters, setFilters] = useState({
  searchTerm: '',
  category: 'all',
  minPrice: 0
});

const filteredItems = allItems.filter(item => {
  const matchesSearch = item.name.toLowerCase().includes(filters.searchTerm.toLowerCase());
  const matchesCategory = filters.category === 'all' || item.category === filters.category;
  const matchesPrice = item.price >= filters.minPrice;
  return matchesSearch && matchesCategory && matchesPrice;
});

方案选择建议

  • 数据集小、筛选逻辑简单:用基础实时筛选方式,代码量最少,维护成本低
  • 数据集大、追求性能:用RTK Query的select选项,减少组件端计算开销
  • 需要复杂筛选状态管理(比如保存筛选条件到URL、持久化筛选状态):可以结合useState或Redux本地状态管理筛选条件,再配合上述两种筛选方式

内容的提问来源于stack exchange,提问作者Derek emmanuel

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.21 11:49:50