Home > database >  After splitting up of react hooks components, the search is not working anymore
After splitting up of react hooks components, the search is not working anymore

Time:02-04

I have been doing a bit of refactoring the code, splitting up of some of the existing big components in react. Earlier the search was working fine, now after splitting it doesn't work as expected. I have created separate component called searchBox and imported into blogItem component. Eventually the blogItem component is imported into Home.js Could someone please advise why the search is not performing here ?

CSB link: https://codesandbox.io/s/quirky-james-t599p2?file=/src/blogItem.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);
  };

  /* Send a GET request to server and get the blog data from contentful website and display in the Home page */
  useEffect(() => {
    setSearchResults(blogData);
  }, []);

  /* Type the blog text in the search box, system will filter the blog post based on the search criteria in the Home page */
  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 }
                    }) // this is how to pass data with useNavigate
                }
              >
                <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;

CodePudding user response:

You are passing props to the SearchBox but not using them since you are using a useCallback inside that component and returning that. Which won't work.

If you remove the useCallback and just run the Searchbox with proper props it'll work.

Here's what I did:

const SearchBox = ({value, onChange}) => {
  return <div className="searchArea">
        ...rest of input code as is
      </div>
}

export default SearchBox;

If you need to optimize it, use memo and memoize the whole component.

Although you really don't need to memoize it as long as the value and onChange stay the same it won't re-render.

Codesandbox link: https://codesandbox.io/s/adoring-dubinsky-9t66ym?file=/src/searchBox.js

  • Related