Error in upgrading code from v5 to v6 in react router dom

Viewed 79

The error is the home page search bar isnt funtioning in v6 in react-router-dom , it isnt visible anymore in header of home page. Thereby i cant seem to understand the best way to render the search bar into header and make it work. Thank you for everyone in advance.

Header.js

import React, { Fragment  } from 'react'
import Search from './Search'
import {Route, useNavigate,Routes} from 'react-router-dom'

const Header = () => {

  return (
    <Fragment>
         <nav className="navbar row">
      <div className="col-12 col-md-3">
        <div className="navbar-brand">
          <img src="./imgs/logos.png" style={{width:'80px',height:'70px'}}/>
        </div>
      </div>

      <div className="col-12 col-md-6 mt-2 mt-md-0">
       <Routes> // **place where the search bar should render** 
       <Route path='/search/:keyword' render={({ navigate }) => <Search navigate={navigate} />} />
       </Routes>
     
      </div>

      <div className="col-12 col-md-3 mt-4 mt-md-0 text-center">
        <button className="btn" id="login_btn">Login</button>

        <span id="cart" className="ml-3">Cart</span>
        <span className="ml-1" id="cart_count">2</span>
      </div>
    </nav>
    </Fragment>
  )
}

export default Header

Search.js

import  React, {useState} from 'react'
import {Link , useLocation, useNavigate } from 'react-router-dom'

const Search = () => {

    const [keyword,setKeyword] = useState('');
  
    let navigate=useNavigate();
    
    const searchHandler= (e) =>{
        e.preventDefault();

        if(keyword){
            navigate(`/search/${keyword}`)
        }else{
            navigate("")
        }




    }

  return (
    <form onSubmit={searchHandler}>
         <div className="input-group">
          <input
            type="text"
            id="search_field"
            className="form-control"
            placeholder="Enter Product Name ..."
            onChange={(e)=> setKeyword(e.target.value) }
          />
          <div className="input-group-append">
            <button id="search_btn" class="btn">
              <i className="fa fa-search" aria-hidden="true"></i>
            </button>
          </div>
        </div>
    </form>
  )
}

export default Search

App.js

import {BrowserRouter as Router,Route,Routes} from 'react-router-dom'

import './App.css';
import Header from './components/layouts/Header';
import Footer from './components/layouts/Footer';
import Home from './components/Home';
import ProductDetails from './components/products/ProductDetails';

function App() {
  return (
    <Router>
    <div className="App">
     <Header/>
     <div className="container container-fluid">
       <Routes>
            <Route path="/" element={<Home/>} />
            <Route path="/product/:id" element={<ProductDetails/>}  />
            <Route path="/search/:keyword" element={Home} />
            </Routes>
        </div>
     <Footer/>
    </div>
    </Router>
  );
}

export default App;
2 Answers

It is not working because you haven't nested the routes tag in router tag in your Header function.

Replace your Header function with below code:

const Header = () => {

  return (
    <Fragment>
      <Router>
         <nav className="navbar row">
      <div className="col-12 col-md-3">
        <div className="navbar-brand">
          <img src="./imgs/logos.png" style={{width:'80px',height:'70px'}}/>
        </div>
      </div>

      <div className="col-12 col-md-6 mt-2 mt-md-0">
       <Routes> // **place where the search bar should render** 
       <Route path='/search/:keyword' render={({ navigate }) => <Search navigate={navigate} />} />
       </Routes>
     
      </div>

      <div className="col-12 col-md-3 mt-4 mt-md-0 text-center">
        <button className="btn" id="login_btn">Login</button>

        <span id="cart" className="ml-3">Cart</span>
        <span className="ml-1" id="cart_count">2</span>
      </div>
    </nav>
      </Router>
    </Fragment>
  )
} 

react-router-dom@6 Route components have no render prop. They have only an element prop to render routed components on as JSX. To render Search when the home page comes out, where the header is part of the home page, render it on the same paths as Home.

<Routes>
  <Route path='/' element={<Search />} />
  <Route path='/search/:keyword' element={<Search />} />
</Routes>

Home

function App() {
  return (
    <Router>
      <div className="App">
        <Header />
        <div className="container container-fluid">
          <Routes>
            <Route path="/" element={<Home />} />
            <Route path="/search/:keyword" element={<Home />} />
            <Route path="/product/:id" element={<ProductDetails />}  />
          </Routes>
        </div>
        <Footer />
      </div>
    </Router>
  );
}
Related