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

如何使用Redux Toolkit、React和JavaScript实现全局搜索筛选?

问题:如何将API返回的商品数组存入Redux的initialState并实现搜索筛选

我需要开发一个基于商品标题的全局搜索筛选功能,用Redux管理全局状态,已经创建了用于筛选标题的reducer,但不知道怎么把API返回的对象数组存入initialState的data数组中;调用API用的是Redux Toolkit的createAPI。

现有代码

searchSlice 代码

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

const searchSlice = createSlice({
  name: "search",
  initialState: {
    data: [], // 用于存储API返回的对象数组
    filteredTitle: [],
    isLoading: true
  },
  reducers: {
    getData: (state, action) => {
      state.data = action.payload;
    },
    searchByName: (state, action) => {
      const filteredResult = state.data.filter((product) =>
        product.title.toLowerCase().includes(action.payload.toLowerCase())
      );
      return {
        ...state,
        filteredTitle:
          action.payload.length > 0 ? filteredResult : [...state.data]
      };
    }
  }
});

export const { searchByName, getData } = searchSlice.actions;
export default searchSlice.reducer;

App.js 代码

import React, { useState, useEffect } from "react";
import { useDispatch, useSelector } from "react-redux";
import { searchByName, getData } from "./features/slice";
import { useGetAllProductsQuery } from "./services/api";

export default function App() {
  const dispatch = useDispatch();
  const filteredTitle = useSelector((state) => state.search.filteredTitle);
  const [searchTerm, setSearch] = useState("");
  const { data } = useGetAllProductsQuery();

  console.log("data", data);

  const changeSearchTerm = (e) => {
    setSearch(e.target.value);
  };

  useEffect(() => {
    dispatch(searchByName(searchTerm));
    dispatch(getData(data));
  }, [searchTerm, dispatch]);

  return (
    <div>
      <input onChange={changeSearchTerm} type="text" value={searchTerm} />
      <div>
        {filteredTitle.map((user) => (
          <div>{user.name}</div>
        ))}
      </div>
    </div>
  );
}

解决方案

1. 修正API数据的存储时机

当前代码在搜索词变化时才尝试存储API数据,会导致data初始为undefined时存入错误值。需要单独监听data的变化,确保数据存在时再存入Redux:

// App.js 中修改 useEffect
useEffect(() => {
  // 仅当API返回有效数据时,存入Redux
  if (data) {
    dispatch(getData(data));
  }
}, [data, dispatch]);

// 单独处理搜索逻辑,仅在搜索词变化时触发筛选
useEffect(() => {
  dispatch(searchByName(searchTerm));
}, [searchTerm, dispatch]);

2. 优化Redux Slice的reducer逻辑

Redux Toolkit支持直接修改state(内部会自动处理不可变更新),可以简化searchByName的写法:

// searchSlice 中修改 searchByName reducer
searchByName: (state, action) => {
  const searchValue = action.payload.toLowerCase();
  // 根据搜索词筛选,无搜索词时返回全部数据
  state.filteredTitle = searchValue 
    ? state.data.filter(product => product.title.toLowerCase().includes(searchValue))
    : [...state.data];
}

3. 修正渲染字段错误

当前渲染的user.name与API返回的商品字段不符,应改为product.title,同时添加唯一key:

// App.js 中修改渲染部分
{filteredTitle.map((product) => (
  <div key={product.id}>{product.title}</div>
))}

4. 处理初始加载状态(可选)

可以利用RTK Query的isLoading状态来优化用户体验:

// App.js 中解构RTK Query的状态
const { data, isLoading } = useGetAllProductsQuery();

// 渲染时添加加载提示
if (isLoading) return <div>加载中...</div>;

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.01 19:40:34