1

I dont know how I am getting the error Mainly, When I tried to add navLink I am getting this error,But when I remove the navLink everything works fine,I dont know how to fix it pls help me to solve the error. I am navigating through a different link on the navBar I dont know how am I getting the problem This is the error -:

utils.ts:757 Uncaught Error: useLocation() may be used only in the context of a <Router> component.
    at invariant (utils.ts:757:1)
    at useLocation (hooks.tsx:97:1)
    at useResolvedPath (hooks.tsx:305:1)
    at NavLinkWithRef (index.tsx:444:1)
    at renderWithHooks (react-dom.development.js:16305:1)
    at updateForwardRef (react-dom.development.js:19226:1)
    at beginWork (react-dom.development.js:21636:1)
    at HTMLUnknownElement.callCallback (react-dom.development.js:4164:1)
    at Object.invokeGuardedCallbackDev (react-dom.development.js:4213:1)
    at invokeGuardedCallback (react-dom.development.js:4277:1)
3react-dom.development.js:18687 The above error occurred in the <NavLink> component:

    at NavLinkWithRef (http://localhost:3000/static/js/bundle.js:42213:23)
    at li
    at ul
    at div
    at div
    at div
    at div
    at Row (http://localhost:3000/static/js/bundle.js:52776:7)
    at div
    at Container (http://localhost:3000/static/js/bundle.js:52735:7)
    at header
    at Header
    at Layouts
    at App

Consider adding an error boundary to your tree to customize error handling behavior.
Visit https://reactjs.org/link/error-boundaries to learn more about error boundaries.
logCapturedError @ react-dom.development.js:18687
react-dom.development.js:26923 Uncaught Error: useLocation() may be used only in the context of a <Router> component.
    at invariant (utils.ts:757:1)
    at useLocation (hooks.tsx:97:1)
    at useResolvedPath (hooks.tsx:305:1)
    at NavLinkWithRef (index.tsx:444:1)
    at renderWithHooks (react-dom.development.js:16305:1)
    at updateForwardRef (react-dom.development.js:19226:1)
    at beginWork (react-dom.development.js:21636:1)
    at beginWork$1 (react-dom.development.js:27426:1)
    at performUnitOfWork (react-dom.development.js:26557:1)
    at workLoopSync (react-dom.development.js:26466:1)
index.js:2139 Canvas2D: Multiple readback operations using getImageData are faster with the willReadFrequently attribute set to true. See: https://html.spec.whatwg.org/multipage/canvas.html#concept-canvas-will-read-frequently
analyzeImage @ index.js:2139
localhost/:1 Uncaught (in promise) Objectmessage: "A listener indicated an asynchronous response by returning true, but the message channel closed before a response was received"[[Prototype]]: Object
localhost/:1 Uncaught (in promise) Objectmessage: "A listener indicated an asynchronous response by returning true, but the message channel closed before a response was received"[[Prototype]]: Object

And the code is -:

import React from 'react';
import { NavLink } from 'react-router-dom';
import { Container, Row } from 'reactstrap';
import Logo from '../../assets/images/logo.png';
import './header.styles.css'

const Header = () => {
  return (
    <header className='header'>
      <Container>
        <Row>
          <div className="nav_wrapper">
            <div className="logo">
              <img src={Logo} alt="logo" />
              <div>
                <h1>Excellence E-commerce</h1>
              </div>
            </div>
            <div className="navigation">
              <div className="menu">
                <ul className="menu">
                  <li className="nav__items">
                    <NavLink>Home</NavLink>
                  </li>
                  <li className="nav_items">
                    <NavLink to="/shop">Shop</NavLink>
                  </li>
                  <li className="nav_items">
                    <NavLink>Cart</NavLink>
                  </li>
                </ul>
              </div>
            </div>

            {/* <div className="nav__icons">
              <span className="cart__icon"></span>
            </div> */}

          </div>
        </Row>
      </Container>
    </header>
  )
};

export default Header


import { BrowserRouter as Router,Routes,Route } from 'react-router-dom';
import React from 'react';
import Home from './Pages/Home/Home';
import Shop from './Pages/Shop/Shop';
import Cart from './Pages/Cart/Cart';
import Checkout from './Pages/Checkout/Checkout';
import Login from './Pages/Login/Login';
import ProductDetail from './Pages/ProductsDetail/ProductDetails';
import Signup from './Pages/Signup/Signup';


const Routers = () => {
  return (
    <Router>
      <Routes>
        <Route exact path='/' index element={<Home />}/>
        <Route path='shop' element={<Shop />} />
        <Route path='/shop/:id' element={<ProductDetail />}/>
        <Route path='/cart' element={<Cart />}/>
        <Route path='/checkout' element={<Checkout />}/>
        <Route path='/login' element={<Login />}/>
        <Route path='/signup' element={<Signup />}/>
      </Routes>
    </Router>
  )
}

export default Routers

And the code where I imported header is at layouts

import React from 'react';
import Header from '../Header/Header';
import Footer from '../Footer/Footer';
import Routers from '../../Routers/Routers';

const Layouts = () => {
  return (
    <>
    <Header />
    <div><Routers /></div>
    <Footer />
    </>
  )
}

export default Layouts
Janab Ali
  • 15
  • 1
  • 5

1 Answers1

0

It's as the error states, the links the Header component is rendering need to be rendered within the routing context provided by a router component. Move rendering the Header component into the Router so it has a routing context provided higher in the ReactTree.

import { BrowserRouter as Router, Routes, Route } from 'react-router-dom';
import React from 'react';
import Home from './Pages/Home/Home';
import Shop from './Pages/Shop/Shop';
import Cart from './Pages/Cart/Cart';
import Checkout from './Pages/Checkout/Checkout';
import Login from './Pages/Login/Login';
import ProductDetail from './Pages/ProductsDetail/ProductDetails';
import Signup from './Pages/Signup/Signup';
import Header from '../path/to/Header'; // <-- import Header

const Routers = () => {
  return (
    <Router>
      <Header /> // <-- render within Router
      <Routes>
        <Route path='/' element={<Home />} />
        <Route path='shop' element={<Shop />} />
        <Route path='/shop/:id' element={<ProductDetail />} />
        <Route path='/cart' element={<Cart />} />
        <Route path='/checkout' element={<Checkout />} />
        <Route path='/login' element={<Login />} />
        <Route path='/signup' element={<Signup />} />
      </Routes>
    </Router>
  );
};

If you are trying to use a specific layout then you can promote the Router component higher in the tree.

Example:

import React from 'react';
import { BrowserRouter as Router } from 'react';
import Header from '../Header/Header';
import Footer from '../Footer/Footer';
import Routers from '../../Routers/Routers';

const Layouts = () => {
  return (
    <Router>
      <Header />
      <div>
        <Routers />
      </div>
      <Footer />
    </Router>
  );
};

export default Layouts;

And remove the Router from Routers.

const Routers = () => {
  return (
    <Routes>
      <Route path='/' element={<Home />} />
      <Route path='shop' element={<Shop />} />
      <Route path='/shop/:id' element={<ProductDetail />} />
      <Route path='/cart' element={<Cart />} />
      <Route path='/checkout' element={<Checkout />} />
      <Route path='/login' element={<Login />} />
      <Route path='/signup' element={<Signup />} />
    </Routes>
  );
};

An alternative is to convert Layouts to an actual layout route.

Example:

import React from 'react';
import { BrowserRouter as Router, Outlet } from 'react';
import Header from '../Header/Header';
import Footer from '../Footer/Footer';

const AppLayout = () => {
  return (
    <Router>
      <Header />
      <div>
        <Outlet /> // <-- nested routes render content here
      </div>
      <Footer />
    </Router>
  );
};

...

...
import AppLayout from '../path/to/AppLayout';

const Routers = () => {
  return (
    <Routes>
      <Route element={<AppLayout />}>
        <Route path='/' element={<Home />} />
        <Route path='shop' element={<Shop />} />
        <Route path='/shop/:id' element={<ProductDetail />} />
        <Route path='/cart' element={<Cart />} />
        <Route path='/checkout' element={<Checkout />} />
        <Route path='/login' element={<Login />} />
        <Route path='/signup' element={<Signup />} />
      </Route>
    </Routes>
  );
};
Drew Reese
  • 165,259
  • 14
  • 153
  • 181
  • Not working Already done that.The think is I have routed through different way-: import React from 'react'; import Header from '../Header/Header'; import Footer from '../Footer/Footer'; import Routers from '../../Routers/Routers'; const Layouts = () => { return ( <>
    > ) } export default Layouts
    – Janab Ali Oct 21 '22 at 08:43
  • @JanabAli It's the correct location, the links need to be inside the router. Can you clarify what isn't working when you move the header into the router? – Drew Reese Oct 21 '22 at 08:44
  • @JanabAli Oh, are you trying to also use a specific layout? – Drew Reese Oct 21 '22 at 08:47
  • I solved the error now everything worked – Janab Ali Oct 21 '22 at 08:57