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

React Hooks下全局导航栏搜索框实现多组件数据过滤的方案问询

React 通用搜索框跨组件过滤的最优实现方案

针对你遇到的「无法通过自定义 Hooks 传递搜索状态到其他组件」的问题,以下是三种不同场景下的最优实现方案,均基于 React Hooks 生态:

1. Context API + 自定义 Hook(推荐中大型应用)

利用 React 原生的 Context 实现全局状态共享,搭配自定义 Hook 简化状态调用,无需额外依赖,是最通用的解决方案。

实现步骤

1.1 创建搜索上下文与自定义 Hook

// SearchContext.js
import { createContext, useContext, useState } from 'react';

const SearchContext = createContext();

// 提供上下文的组件
export function SearchProvider({ children }) {
  const [searchQuery, setSearchQuery] = useState('');

  return (
    <SearchContext.Provider value={{ searchQuery, setSearchQuery }}>
      {children}
    </SearchContext.Provider>
  );
}

// 封装自定义 Hook 简化调用
export function useSearch() {
  return useContext(SearchContext);
}

1.2 在根组件中包裹上下文

// App.js
import { SearchProvider } from './SearchContext';
import Navbar from './Navbar';
import ProductList from './ProductList';

function App() {
  return (
    <SearchProvider>
      <Navbar />
      <ProductList />
    </SearchProvider>
  );
}

1.3 导航栏搜索框更新状态

// Navbar.js
import { useSearch } from './SearchContext';

function Navbar() {
  const { searchQuery, setSearchQuery } = useSearch();

  return (
    <nav>
      <input
        type="text"
        value={searchQuery}
        onChange={(e) => setSearchQuery(e.target.value)}
        placeholder="搜索商品..."
      />
    </nav>
  );
}

1.4 目标组件使用状态过滤数据

// ProductList.js
import { useSearch } from './SearchContext';

function ProductList() {
  const { searchQuery } = useSearch();
  const allProducts = ['笔记本电脑', '无线耳机', '机械键盘', '游戏手柄'];

  // 根据搜索关键词过滤数据
  const filteredProducts = allProducts.filter(item => 
    item.toLowerCase().includes(searchQuery.toLowerCase())
  );

  return (
    <ul>
      {filteredProducts.map(product => (
        <li key={product}>{product}</li>
      ))}
    </ul>
  );
}

2. 自定义 Hook + 事件总线(适合小型应用)

如果不想引入 Context 的嵌套层级,可通过事件总线实现状态的跨组件通知,轻量化且灵活。

实现步骤

2.1 创建简易事件总线

// eventBus.js
const eventBus = {
  // 订阅事件
  on(eventName, callback) {
    document.addEventListener(`search:${eventName}`, (e) => callback(e.detail));
  },
  // 发布事件
  emit(eventName, data) {
    document.dispatchEvent(new CustomEvent(`search:${eventName}`, { detail: data }));
  },
  // 取消订阅
  off(eventName, callback) {
    document.removeEventListener(`search:${eventName}`, callback);
  }
};

export default eventBus;

2.2 封装自定义 Hook

// useSearchQuery.js
import { useState, useEffect } from 'react';
import eventBus from './eventBus';

export function useSearchQuery() {
  const [searchQuery, setSearchQuery] = useState('');

  // 订阅搜索更新事件
  useEffect(() => {
    const handleUpdate = (query) => setSearchQuery(query);
    eventBus.on('update', handleUpdate);
    // 组件卸载时取消订阅
    return () => eventBus.off('update', handleUpdate);
  }, []);

  // 更新搜索关键词并发布事件
  const updateSearchQuery = (query) => {
    setSearchQuery(query);
    eventBus.emit('update', query);
  };

  return { searchQuery, updateSearchQuery };
}

2.3 导航栏与目标组件使用

导航栏和目标组件直接调用 useSearchQuery Hook 即可,代码逻辑和 Context 方案一致,无需修改根组件结构。

3. Redux Toolkit(适合大型复杂应用)

如果你的应用已经使用 Redux,或需要统一管理多个全局状态,Redux Toolkit 是更规范的选择。

实现步骤

3.1 创建搜索状态 Slice

// features/search/searchSlice.js
import { createSlice } from '@reduxjs/toolkit';

const initialState = {
  query: ''
};

const searchSlice = createSlice({
  name: 'search',
  initialState,
  reducers: {
    setSearchQuery: (state, action) => {
      state.query = action.payload;
    }
  }
});

export const { setSearchQuery } = searchSlice.actions;
export default searchSlice.reducer;

3.2 配置 Redux Store

// store.js
import { configureStore } from '@reduxjs/toolkit';
import searchReducer from './features/search/searchSlice';

export const store = configureStore({
  reducer: {
    search: searchReducer
  }
});

3.3 根组件包裹 Redux Provider

// App.js
import { Provider } from 'react-redux';
import { store } from './store';
import Navbar from './Navbar';
import ProductList from './ProductList';

function App() {
  return (
    <Provider store={store}>
      <Navbar />
      <ProductList />
    </Provider>
  );
}

3.4 导航栏与目标组件使用状态

// Navbar.js
import { useDispatch, useSelector } from 'react-redux';
import { setSearchQuery } from './features/search/searchSlice';

function Navbar() {
  const query = useSelector(state => state.search.query);
  const dispatch = useDispatch();

  return (
    <nav>
      <input
        type="text"
        value={query}
        onChange={(e) => dispatch(setSearchQuery(e.target.value))}
        placeholder="搜索..."
      />
    </nav>
  );
}

目标组件通过 useSelector 获取搜索关键词,过滤逻辑和前两种方案一致。


方案选型建议

  • Context API:优先选择,原生支持、无额外依赖,满足大部分中大型应用需求
  • 事件总线:小型应用或不想引入 Context 时使用,轻量化实现
  • Redux Toolkit:已有 Redux 生态或需要复杂状态管理的大型应用使用

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.09 00:55:32