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

拆分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;

额外优化点

  1. 移除SearchBox中未使用的useState、useEffect、useCallback等钩子和依赖,简化组件
  2. 优化BlogItem的搜索过滤逻辑,避免重复转换字符串大小写:
const results = React.useMemo(() => {
  const lowerTerm = searchTerm.toLowerCase();
  return searchResults.filter(blog => 
    blog.heading.toLowerCase().includes(lowerTerm)
  );
}, [searchTerm, searchResults]);

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.02 15:50:32