React中输入触发的过滤函数无响应,求排查解决
问题根源
你的代码存在两个核心问题导致过滤功能失效:
Search组件中setSearchText是异步状态更新,调用filterCategories时拿到的仍是旧的searchText值Layout组件维护了filteredCategories状态,但没有将过滤后的结果传递给Home组件,导致页面无法展示过滤后的内容
具体调整方案
1. 修复Search组件的异步状态问题
改用useEffect监听searchText变化触发过滤,避免异步更新带来的旧值问题:
import { useState, useEffect } from 'react'; export function Search({categories, onSearch}){ const [searchText, setSearchText] = useState(''); const filterCategories = () => { const filteredCategories = categories.filter(category => category.name.toLowerCase().includes(searchText.toLowerCase()) ); onSearch(filteredCategories); }; // 监听搜索文本变化,自动执行过滤 useEffect(() => { filterCategories(); }, [searchText, categories]); const handleInputChange = event => { setSearchText(event.target.value); }; return ( <div className="flex items-center"> <form className='flex space-x-1' > <input type="text" className="block w-full px-4 py-2 text-purple-700 bg-white border rounded-full focus:border-purple-400 focus:ring-purple-300 focus:outline-none focus:ring focus:ring-opacity-40" placeholder="Search..." value={searchText} onChange={handleInputChange} /> </form> </div> ) }
2. 让Layout传递过滤后的分类数据给Home
修改Layout,将filteredCategories传递给子组件:
import { useState } from 'react'; import React from 'react'; const Layout = ({ categories, children }) => { const [filteredCategories, setFilteredCategories] = useState(categories); const handleSearch = (filteredCategories) => { setFilteredCategories(filteredCategories); }; return ( <div> {/* ...其他布局内容 */} <Search categories={categories} onSearch={handleSearch} /> {/* ...其他布局内容 */} {React.cloneElement(children, { filteredCategories })} </div> ); }; export default Layout;
3. Home组件使用过滤后的数据
在Home中接收filteredCategories,并用来渲染对应内容(示例为过滤帖子):
export default function Home({ posts, categories, filteredCategories }) { // 根据过滤后的分类筛选帖子 const filteredPosts = posts.filter(post => filteredCategories.some(cat => cat.id === post.categoryId) ); return ( <Layout categories={categories}> <div className="mt-20"> <main className="flex flex-col justify-center items-center h-screen pt-10 pb-30"> {/* 渲染过滤后的帖子列表 */} {filteredPosts.map(post => ( <div key={post.id} className="mb-4"> <h3>{post.title}</h3> <p>{post.content}</p> </div> ))} </main> </div> </Layout> ); }
内容的提问来源于stack exchange,提问作者willd
相关产品推荐
相关产品推荐

