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

如何使用useContext实现搜索栏过滤功能 附基础实现代码参考

实现步骤

1. 调整全局上下文(GlobalState)逻辑

首先需要在全局状态中新增搜索关键词的存储和更新方法,确保搜索栏和PizzaList组件可以共享该状态,参考修改后的GlobalState.js代码:

import React, { createContext, useReducer } from 'react';
import pizzaReducer from './reducers/pizzaReducer'; // 替换为你原有reducer的实际路径

const initialState = {
  pizzas: [],
  searchKeyword: '', // 新增搜索关键词存储字段
};

export const GlobalContext = createContext(initialState);

export const GlobalProvider = ({ children }) => {
  const [state, dispatch] = useReducer(pizzaReducer, initialState);

  // 原有获取披萨列表的逻辑保持不变
  const getPizzas = async () => {
    // 此处保留你原有拉取数据的逻辑
  };

  // 新增更新搜索关键词的方法
  const setSearchKeyword = (keyword) => {
    dispatch({
      type: 'SET_SEARCH_KEYWORD',
      payload: keyword
    });
  };

  return (
    <GlobalContext.Provider value={{
      pizzas: state.pizzas,
      searchKeyword: state.searchKeyword,
      getPizzas,
      setSearchKeyword
    }}>
      {children}
    </GlobalContext.Provider>
  );
};

同步在对应的reducer中新增状态处理逻辑:

// pizzaReducer.js 新增对应处理分支
const pizzaReducer = (state, action) => {
  switch(action.type) {
    // 保留你原有的其他case逻辑
    case 'SET_SEARCH_KEYWORD':
      return {
        ...state,
        searchKeyword: action.payload
      };
    default:
      return state;
  }
};

2. 实现搜索栏组件

可以单独抽离搜索栏组件提升复用性,也可以直接将搜索框写在PizzaList组件内:

// SearchBar.js
import React, { useContext } from 'react';
import { GlobalContext } from '../context/GlobalState';

export const SearchBar = () => {
  const { searchKeyword, setSearchKeyword } = useContext(GlobalContext);

  return (
    <div className="search-bar">
      <input
        type="text"
        placeholder="搜索披萨名称、配料..."
        value={searchKeyword}
        onChange={(e) => setSearchKeyword(e.target.value)}
      />
    </div>
  );
};

3. 改造PizzaList组件新增过滤逻辑

在渲染列表前先根据搜索关键词过滤数据,这里默认按披萨名称做模糊匹配,你可以根据业务需求调整匹配字段(比如配料、描述等):

import React, { useContext, useEffect, useMemo } from "react";
import { Pizza } from "./Pizza";
import { SearchBar } from "./SearchBar"; // 引入搜索栏组件
import { GlobalContext } from "../context/GlobalState";

export const PizzaList = () => {
  const { pizzas, getPizzas, searchKeyword } = useContext(GlobalContext);

  useEffect(() => {
    getPizzas();
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, []);

  // 用useMemo缓存过滤结果,仅当披萨列表或搜索关键词变化时才重新计算
  const filteredPizzas = useMemo(() => {
    // 搜索关键词为空时返回全量数据
    if (!searchKeyword.trim()) return pizzas;
    const lowerKeyword = searchKeyword.toLowerCase();
    return pizzas.filter(pizza => 
      // 可自行扩展匹配规则,比如匹配配料 pizza.ingredients.some(item => item.toLowerCase().includes(lowerKeyword))
      pizza.name.toLowerCase().includes(lowerKeyword)
    );
  }, [pizzas, searchKeyword]);

  return (
    <>
      <SearchBar /> {/* 渲染搜索栏 */}
      <h3>History</h3>
      <ul className="list">
        {filteredPizzas.map((pizza) => (
          <Pizza key={pizza.id} pizza={pizza} />
        ))}
        {/* 可选:新增无匹配结果的提示 */}
        {filteredPizzas.length === 0 && searchKeyword.trim() && (
          <li className="no-result">没有找到匹配的披萨</li>
        )}
      </ul>
    </>
  );
};

补充说明:如果你的披萨数据是后端接口返回,也可以选择把搜索关键词传给后端做服务端过滤,仅需在setSearchKeyword时调用后端搜索接口即可,整体逻辑和前端过滤基本一致。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.28 07:06:04