Back

Technologies:

javascriptjavascript
reactjsreactjs
avatar
Tolerim
a month ago

How to implement a search bar in an ecommerce MERN stack?

Currently, I'm working on developing a website using MERN by following a Udemy video tutorial. The tutorial includes a header component with the following code:

<Route render={({ history }) => <Search history={history} />} />
However, I encountered an error and had to modify the code by wrapping it inside Routes. Here's my updated App.js:

<Routes>
  <Route path="/search/:keyword" component={Home} />
  <Route path="/" element={<Search />} />
</Routes>
I also had to modify the Search.js file by adding a few lines of code:

const Search = ({ history }) => {
  const [keyword, setKeyword] = useState('');

  const searchHandler = (e) => {
    e.preventDefault();

    if (keyword.trim()) {
      history.push(`/search/${keyword}`);
    } else {
      history.push('/');
    }
  };

  return (
    <form onSubmit={searchHandler}>
      <input type="text" onChange={(e) => setKeyword(e.target.value)} />
      <button type="submit">Search</button>
    </form>
  );
};
Despite making these changes, the search bar disappeared. After some trial and error, I found a solution by removing the component and replacing it with element in the App.js file. However, this caused the error message "history" is not defined. By removing history from the initial header.js code, I was able to successfully display the search bar without any errors.

Answers(2)
avatar
Vogi
a month ago
Verified Answer
It seems like you are having trouble with your search bar. I think the issue is that you are not passing the history object to the Search component. You can try to pass it as a prop to the Search component in your App.js file like this:
<Routes>
  <Route path="/search/:keyword" element={<Home />} />
  <Route path="/" element={<Search history={history} />} />
</Routes>
This should fix the issue with the search bar disappearing. As for the error message "history is not defined", it seems like you are trying to use the history object in your Search.js file without passing it as a prop. You can try to pass it as a prop like this:
const Search = ({ history }) => {
  const [keyword, setKeyword] = useState('');

  const searchHandler = (e) => {
    e.preventDefault();

    if (keyword.trim()) {
      history.push(/search/${keyword});
    } else {
      history.push('/');
    }
  };

  return (
    <form onSubmit={searchHandler}>
      <input type="text" onChange={(e) => setKeyword(e.target.value)} />
      <button type="submit">Search</button>
    </form>
  );
};
I hope this helps! Let me know if you have any other questions.
avatar
Tolerim
a month ago
It seems like the code you provided is using both React Router v5 (which uses ) and v6 (which uses and differently). To solve the issue, you should stick with one version of React Router. If you want to use v6, you should rewrite your code like this: In App.js:
import { Routes, Route } from 'react-router-dom';

const App = () => {
  return (
    <Routes>
      <Route path="/search/:keyword" element={<Home />} />
      <Route path="/" element={<Search />} />
    </Routes>
  );
};
And in Header.js:
import { useNavigate } from 'react-router-dom';

const Header = () => {
  const navigate = useNavigate();

  const searchHandler = (e) => {
    e.preventDefault();
    navigate(`/search/${keyword}`);
  };

  return (
    <form onSubmit={searchHandler}>
      <input type="text" onChange={(e) => setKeyword(e.target.value)} />
      <button type="submit">Search</button>
    </form>
  );
};
In this code, we're using and from v6, along with the useNavigate hook to navigate to the search page. Also, we're removing the history prop from and using state instead.
;