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

如何在Redux切片状态变化时触发RTK Query请求?

用RTK Query订阅筛选器状态变化并触发请求

核心思路

RTK Query的useQuery会自动追踪查询参数的变化,只要把Redux Store中的筛选器状态作为查询参数传入,就能在筛选条件更新时自动触发新请求。如果需要手动控制触发时机,也可以用useLazyQuery配合useEffect监听筛选器状态变化。


步骤1:创建筛选器状态切片

先定义一个Redux切片来存储筛选器状态,包含更新筛选条件的reducer:

import { createSlice } from '@reduxjs/toolkit';

const initialState = {
  category: '',
  priceRange: '',
  // 按需添加其他筛选字段
};

const filtersSlice = createSlice({
  name: 'filters',
  initialState,
  reducers: {
    updateFilter: (state, action) => {
      const { key, value } = action.payload;
      state[key] = value;
    },
    resetFilters: () => initialState,
  },
});

export const { updateFilter, resetFilters } = filtersSlice.actions;
export default filtersSlice.reducer;

步骤2:自动触发请求(推荐方式)

使用useQuery,直接将筛选器状态作为查询参数传入。当筛选器状态变化时,RTK Query会自动对比参数差异,发起新请求:

import { useSelector, useDispatch } from 'react-redux';
import { useGetDataQuery } from './apiSlice'; // 你的RTK Query API切片
import { updateFilter } from './filtersSlice';

function DataListPage() {
  const dispatch = useDispatch();
  // 从Redux Store获取当前筛选器状态
  const filters = useSelector(state => state.filters);

  // 将筛选器作为查询参数,参数变化时自动重新请求
  const { data, error, isLoading } = useGetDataQuery(filters);

  return (
    <div>
      {/* 分类筛选下拉框 */}
      <select
        value={filters.category}
        onChange={(e) => {
          dispatch(updateFilter({ key: 'category', value: e.target.value }));
        }}
      >
        <option value="">所有分类</option>
        <option value="electronics">电子产品</option>
        <option value="clothing">服饰</option>
      </select>

      {/* 价格区间筛选(示例) */}
      <select
        value={filters.priceRange}
        onChange={(e) => {
          dispatch(updateFilter({ key: 'priceRange', value: e.target.value }));
        }}
      >
        <option value="">不限价格</option>
        <option value="0-100">0-100元</option>
        <option value="100-500">100-500元</option>
      </select>

      {/* 数据渲染 */}
      {isLoading && <div>加载中...</div>}
      {error && <div>请求失败:{error.message}</div>}
      {data && (
        <ul>
          {data.map(item => (
            <li key={item.id}>{item.name} - {item.price}元</li>
          ))}
        </ul>
      )}
    </div>
  );
}

export default DataListPage;

步骤3:手动控制请求触发时机

如果需要更灵活的触发逻辑(比如点击"搜索"按钮才请求),可以用useLazyQuery配合useEffect监听筛选器变化:

import { useSelector, useDispatch } from 'react-redux';
import { useLazyGetDataQuery } from './apiSlice';
import { updateFilter } from './filtersSlice';
import { useEffect } from 'react';

function DataListPage() {
  const dispatch = useDispatch();
  const filters = useSelector(state => state.filters);
  // 初始化lazy query,返回触发函数和请求状态
  const [triggerGetData, { data, error, isLoading }] = useLazyGetDataQuery();

  // 监听筛选器变化,自动触发请求
  useEffect(() => {
    triggerGetData(filters);
  }, [filters, triggerGetData]);

  // 或者添加按钮手动触发
  const handleSearch = () => {
    triggerGetData(filters);
  };

  return (
    <div>
      {/* 筛选器组件 */}
      <button onClick={handleSearch}>搜索</button>
      {/* 数据渲染 */}
    </div>
  );
}

优化:避免不必要的请求

如果筛选器对象包含多个字段,部分字段变化不影响请求,可以用useMemo缓存处理后的参数,减少无效请求:

import { useMemo } from 'react';

// ...

const filtersQueryParam = useMemo(() => {
  // 过滤空值或不需要的字段,生成稳定的请求参数
  return Object.fromEntries(
    Object.entries(filters).filter(([_, value]) => value !== '')
  );
}, [filters]);

const { data, error, isLoading } = useGetDataQuery(filtersQueryParam);

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.03 23:50:26