Avoid using the Router with the Search component in React JS

Having trouble rendering my Search component within the main Header component using react-router-dom.

I suspect there's an issue with this line of code <Route render={({ history }) => } />

I've been stuck on this for two days now...

Trying to add a search feature to the website but can't seem to get it working

Please assist :D

Header.js

import React, { Fragment } from 'react';
import { Route, Routes } from 'react-router-dom';

import Search from './Search';

import '../../App.css';

const Header = () => {
  return (
    <Fragment>
      <nav className='navbar row'>
        <div className='col-12 col-md-3'>
          <div className='navbar-brand'>
            <img src='/images/shopit_logo.png' alt='Site logo' />
          </div>
        </div>

        <div className='col-12 col-md-6 mt-2 mt-md-0'>
          <Routes>
            <Route render={({ history }) => <Search history={history} />} />
          </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

mport React, { useState } from 'react';

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}>
      <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' className='btn'>
            <i className='fa fa-search' aria-hidden='true'></i>
          </button>
        </div>
      </div>
    </form>
  );
};

export default Search;

//App.js

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

import Header from './components/layout/Header';
import Footer from './components/layout/Footer';

import Home from './components/Home';
import ProductDetails from './components/product/ProductDetails';

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

export default App;

Answer №1

Problem

The issue at hand is as follows:

<Routes>
  <Route render={({ history }) => <Search history={history} />} />
</Routes>

In react-router-dom version 6, the Route components no longer support the component, render, or children function props. Additionally, the old route props are no longer available. RRDv6 also utilizes a navigate function instead of exposing the history object.

Solution

Since the Search component is a functional component, you can import and utilize the useNavigate hook to replace the usage of history.push with navigate.

Header.js

<div className='col-12 col-md-6 mt-2 mt-md-0'>
  <Search />
</div>

Search.js

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

const Search = () => {
  const navigate = useNavigate();
  const [keyword, setKeyword] = useState('');

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

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

  return (
    <form onSubmit={searchHandler}>
      ...
    </form>
  );
};

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Utilizing CSS-in-JS to eliminate arrow buttons from a TextField

I'm currently developing a webpage using React and Material-UI. One of the components I have is a TextField element, and I need to remove the arrow buttons that typically appear on number input fields. If I were utilizing CSS, I could easily achieve t ...

Refresh Form (Reactive Forms)

This is the HTML code snippet: <div class="container"> <ng-template [ngIf]="userIsAuthenticated"> <form [formGroup]='form' name="test"> <div class="form-group"> <input type="text" class="form-contr ...

Transferring JSON data using $.post in Express/NodeJS

Below is the contents of my app.js file: var express = require('express'); var app = express(); var path = require('path'); var $ = require('jquery'); var nodemailer = require('nodemailer'); app.use('/static&a ...

Angular does not delay for promises to settle

Issue I am facing is related to Angular not waiting for promises to be resolved. The console inspection reveals that the provider and skills objects are not retrieved before the promises are returned. I have included the key parts of the code below. The s ...

What methods does Coinbase use to achieve this effect? Is it possible to recreate it in a React application? (Dropdown menu positioned relative to a button on hover or click

Notice the hover effect on the Businesses section, where a prepositioned dropdown menu appears, spanning the full width of the screen. How was this effect achieved and can it be recreated in React if it wasn't originally coded using React? https://i. ...

JQuery ID Media Queries: Enhancing responsive design with targeted

Is it possible to integrate a media query into the selection of an ID using JQuery? For example: $('#idname') $('@media (max-width: 767px) { #idname }') In essence, can you target the #idname with that specified media query in JQuery ...

Could anyone lend a hand in ensuring that my AJAX call successfully processes the parameters?

When attempting to retrieve specific data from my database using AJAX, I encountered an issue where the call was successful when made through Postman or directly in the browser, but failed when initiated from my client. It seemed to work intermittently, re ...

Transforming Node's loops into asynchronous functions

I have the following sync function: for (var i = 0; i < results.length; i++) { var key1 = results[i]['__key']; for (var j = i + 1; j < results.length; j++) { ...

Using CKEditor in an AngularJS web application: Tips and tricks

I'm having trouble integrating the ckeditor into an HTML page that's built with angularjs. Despite trying out numerous examples, such as the ng-ckeditor and ckeditor directives, I haven't found a solution that works for me. What I need is ...

Change the data returned by Ajax

After making an ajax request, my table gets populated with data from my array. The return is as expected, but now I want to modify this data before displaying it to the user. Whether this modification happens before or after the data is placed in the table ...

What is the best way to determine the final letter of a column in a Google Sheet, starting from the first letter and using a set of

My current approach involves generating a single letter, but my code breaks if there is a large amount of data and it exceeds column Z. Here is the working code that will produce a, d: const countData = [1, 2, 3, 4].length; const initialLetter = 'A&a ...

Unexpectedly, the React custom component is failing to render as intended

I am anticipating the text "SMALL Medium, Big" to be displayed on the screen but unfortunately it's not showing up function Box(prop){ const ele = <div className={prop.cn}> </div> return ele } ...

Exploring the world of Node.js, JSON, SQL, and database tables

Hello everyone, I have been working on a project using Node.js and Express framework. My current goal is to create a client-side page that allows users to input form data into a MySQL database. I have managed to successfully insert and retrieve data from ...

React Navigation - Error: Attempting to access the property 'toUpperCase' of an undefined value

Running into an issue while working with React. Unable to find a solution so far. The stack trace isn't very helpful due to webpack bundling. This is the output I see in the console: [HMR] Waiting for update signal from WDS... Warning: React.createE ...

I'm trying to create a drop-down list in JS that will save selected options to a database using PHP. I'm feeling a bit lost, anyone

My goal is to upload a pdf file with specific options that determine its category. The challenge arises when creating multiple options, as the second option depends on the first choice and involves JavaScript functionality for which I am unsure how to stor ...

Displaying JSON data in HTML using Angular

If you have a straightforward controller: controller: function($scope, $http){ $http.get(templateSource+'/object.customer') .then(function(result){ $scope = result.data; }); } The content of my object.customer file is a ...

tips for personalizing your jQuery image preview script

Currently, I have implemented a jQuery script that allows me to preview multiple images before uploading them. Although the functionality works well, I am facing difficulties customizing it to meet my specific requirements. <script> $(document).r ...

Challenges with fetching data from APIs in NextJs

I am currently working on a basic NextJs TypeScript application with the app router. The following code is functioning correctly: export default async function Page() { const res = await fetch("https://api.github.com/repos/vercel/next.js"); ...

Preventing line breaks (endline) from PHP variable when passing to JavaScript

Check out my code snippet below: <td onclick="openFile('<?php echo htmlentities ($row['name'])?>',' <?php echo htmlentities ($row['content'])?>')"> <a href="#nf" dat ...

Can AngularJS Filters be used to convert a number into a string, but not the other way around?

After researching Angular JS filters, I discovered that the number filter is used to format a number as a string. However, there doesn't seem to be a built-in filter for converting a string to a number. In an attempt to solve this issue, here is so ...