拆分React Hooks组件后搜索功能失效,求助排查原因
问题排查:React拆分组件后搜索功能失效
最近重构React项目,拆分了原有大型组件,将搜索框拆成独立的SearchBox组件,引入到BlogItem后再导入到Home.js中,但原本正常的搜索功能现在失效了。
相关代码
searchBox.js
import React, { useState, useEffect, useCallback } from "react"; import { useMediaQuery } from "react-responsive"; import { NavLink } from "react-router-dom"; const SearchBox = () => { const SearchArea = useCallback( ({ value, onChange }) => ( <div className="searchArea"> {/* {isPortrait ? "" : ""} */} <div className="row"> <div className="searchbox"> <div className="sboxcolumnn-1"> <img src="images/search.png" /> </div> <input type="text" name="searchbox" placeholder="search blogs..." value={value} onChange={onChange} ></input> </div> </div> </div> ), [] ); return <SearchArea />; }; export default SearchBox;
blogItem.js
import "./styles.css"; import React, { useState, useEffect, useCallback } from "react"; import { useNavigate } from "react-router-dom"; import SearchBox from "./searchBox"; const blogData = [ { id: 1, date: "25 Jan 2023", photo: "https://picsum.photos/80", heading: "Cypress setup blog", blogDetails: "Best heading added here. The most relevant data added here. Greatest of all time. Wont be a good idea play here always." }, { id: 2, date: "22 Jan 2022", photo: "https://picsum.photos/80", heading: "React state details", blogDetails: "Best heading added here. The most relevant data added here. Greatest of all time. Wont be a good idea play here always." } ]; const BlogItem = ({ id, date, photo, heading, blogDetails }) => { const [searchResults, setSearchResults] = useState([]); const [searchTerm, setSearchTerm] = useState(""); const navigate = useNavigate(); const handleChange = (e) => { setSearchTerm(e.target.value); }; /* 从服务器获取博客数据并展示在首页 */ useEffect(() => { setSearchResults(blogData); }, []); /* 根据搜索框内容过滤博客 */ const results = React.useMemo( () => searchResults.filter((blog) => { return ( blog.heading.toLowerCase().includes(searchTerm) || blog.heading.toUpperCase().includes(searchTerm) ); }), [searchTerm, searchResults] ); const Columns = () => ( <div className="blogItems"> <div className="row"> <div className="blogArea"> {results.map(({ id, date, photo, heading, blogDetails }) => ( <a key={id}> <div className="blogImageSection" onClick={ () => navigate("blogDetails", { state: { id, date, photo, heading, blogDetails } }) } > <img alt="id" src={photo} /> <div key={id} className="dataArea"> <span className="dataDate">{date}</span> <span className="tags">cypress</span> <h3>{heading}</h3> <p> Best heading added here. The most relevant data added here. Greatest of all time. Wont be a good idea play here always. </p> <a href="_blank" className="readmoreLink"> Read more → </a> </div> </div> </a> ))} </div> </div> </div> ); return ( <> <SearchBox value={searchTerm} onChange={handleChange} /> <Columns /> </> ); }; export default BlogItem;
Home.js
import "./styles.css"; import React, { useState, useEffect, useCallback } from "react"; import BlogItem from "./blogItem"; const Home = () => { return ( <div id="App"> <BlogItem /> </div> ); }; export default Home;
问题原因
搜索功能失效的核心问题出在SearchBox组件:
SearchBox没有接收父组件传递的value和onChange属性,父组件BlogItem传的props完全没被利用- 内部定义的
SearchArea虽然声明了接收value和onChange,但SearchBox返回<SearchArea />时没有传递任何props,导致input的value和onChange始终为undefined,无法与父组件的searchTerm状态联动
另外,SearchBox中引入的useMediaQuery和NavLink没有实际使用,属于冗余依赖。
修复方案
修改SearchBox组件,让它正确接收并传递props:
import React from "react"; const SearchBox = ({ value, onChange }) => { return ( <div className="searchArea"> <div className="row"> <div className="searchbox"> <div className="sboxcolumnn-1"> <img src="images/search.png" /> </div> <input type="text" name="searchbox" placeholder="search blogs..." value={value} onChange={onChange} /> </div> </div> </div> ); }; export default SearchBox;
额外优化点
- 移除
SearchBox中未使用的useState、useEffect、useCallback等钩子和依赖,简化组件 - 优化
BlogItem的搜索过滤逻辑,避免重复转换字符串大小写:
const results = React.useMemo(() => { const lowerTerm = searchTerm.toLowerCase(); return searchResults.filter(blog => blog.heading.toLowerCase().includes(lowerTerm) ); }, [searchTerm, searchResults]);
内容的提问来源于stack exchange,提问作者soccerway
相关产品推荐
相关产品推荐

