使用Redux实现全局搜索筛选:Navbar搜索栏联动兄弟组件博客过滤求助
实现方案
方案1:状态提升(无第三方依赖,最推荐)
同级兄弟组件无法直接传值,最轻量化的实现方式是将共享状态提升到两个组件的公共父组件中存储,步骤如下:
- 第一步:父组件定义搜索关键字状态、更新方法,以及筛选逻辑
// 公共父组件 App.jsx import { useState } from 'react' import Navbar from './Navbar' import BlogList from './BlogList' function App() { // 共享搜索关键字状态 const [searchKey, setSearchKey] = useState('') // 原始博客数据,可从接口获取或存在状态管理中 const originBlogs = [ {id:1, title:'React入门教程', content:'xxx'}, {id:2, title:'Vue实战技巧', content:'xxx'}, {id:3, title:'JavaScript高级用法', content:'xxx'} ] // 实时筛选逻辑,不区分大小写 const filteredBlogs = originBlogs.filter(blog => blog.title.toLowerCase().includes(searchKey.toLowerCase()) ) return ( <div className="App"> <Navbar setSearchKey={setSearchKey} /> <BlogList blogs={filteredBlogs} /> </div> ) }
- 第二步:Navbar组件接收状态更新方法,绑定到搜索框的
onChange事件
// Navbar.jsx function Navbar({ setSearchKey }) { return ( <nav className="navbar"> <input type="text" placeholder="搜索博客..." onChange={(e) => setSearchKey(e.target.value)} /> </nav> ) }
- 第三步:BlogList组件直接接收筛选后的数据渲染
// BlogList.jsx function BlogList({ blogs }) { return ( <div className="blog-list"> {blogs.length === 0 ? ( <p>无匹配博客</p> ) : ( blogs.map(blog => ( <div key={blog.id} className="blog-item"> <h3>{blog.title}</h3> <p>{blog.content}</p> </div> )) )} </div> ) }
筛选逻辑也可以放在BlogList组件内部,只需要父组件把
searchKey和原始博客数据同时传给BlogList即可,可根据项目结构灵活调整。
方案2:全局状态管理(适合中大型项目)
如果项目已经接入Redux、Zustand、Jotai等全局状态管理工具,可以直接把搜索关键字存到全局store中,两个组件分别读写即可,无需通过父组件透传参数,以Zustand为例:
- 定义全局store
// store.js import { create } from 'zustand' const useBlogStore = create((set) => ({ searchKey: '', setSearchKey: (key) => set({ searchKey: key }), }))
- Navbar中调用更新方法
function Navbar() { const setSearchKey = useBlogStore(state => state.setSearchKey) return <input onChange={(e) => setSearchKey(e.target.value)} placeholder="搜索博客" /> }
- BlogList中读取状态做筛选
function BlogList() { const searchKey = useBlogStore(state => state.searchKey) const originBlogs = [...] // 原始博客数据 const filteredBlogs = originBlogs.filter(blog => blog.title.toLowerCase().includes(searchKey.toLowerCase())) // 渲染逻辑和方案1一致 }
优化提示
如果博客数据量较大,输入时频繁筛选可能出现卡顿,可以加防抖逻辑降低筛选触发频率:
// 防抖工具函数 const debounce = (func, delay) => { let timer return (...args) => { clearTimeout(timer) timer = setTimeout(() => func.apply(this, args), delay) } } // Navbar中使用,延迟300ms触发筛选 const handleSearch = debounce((value) => setSearchKey(value), 300) // 输入框onChange改为:onChange={(e) => handleSearch(e.target.value)}
内容的提问来源于stack exchange,提问作者krishna-chavan
相关产品推荐
相关产品推荐

