Search code examples
javascriptreactjsreact-routerreact-router-dom

useNavigate() may be used only in the context of a <Router> component. react-router-dom version 6.12.0


useNavigate() may be used only in the context of a <Router> component.

react-router-dom version is ^6.12.0.

As shown above, we have a problem. What do you recommend to do?

Header

Merchant button on navbar is not working when it is clicked.

See my code.

import React from "react";
import "./css/header.css";
import { Menu } from "antd";
import { Link, useNavigate } from "react-router-dom";

const items = [
  { label: "Merchants", path: <Link to="/merchant" />, key: "merchant" },
  { label: "Customers", path: <Link to="/customer" />, key: "customer" },
];

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

  const handleMenuClick = ({ key }) => {
    if (key) {
      console.log(key)
      navigate(key);
    }
  };

  return (
    <div className="cc-nav">
      <div className="cc-nav-body">
        <Menu
          defaultSelectedKeys={["/merchant"]}
          mode="horizontal" items={items}
          onClick={handleMenuClick}
        />
      </div>
    </div>
  );
};

export default Header;

routes.js file

import React from "react";
const Dashboard = React.lazy(() => import('../containers/TheContent'));
const Merchant = React.lazy(() => import('../pages/merchant/pages/Merchant'));

const routes = [
  { path: '/', name: 'Dashboard', element: <Dashboard /> },
  { path: '/merchant', name: 'Merchant', element: <Merchant /> },
]

export default routes;

App.js file

import 'antd/dist/antd';
import { ConfigProvider } from "antd";
import './App.css';
import TheLayout from "./containers/TheLayout";
import { Suspense } from "react";
import { BrowserRouter, Routes, Route } from 'react-router-dom';
import routes from './router/routes';

function App() {
  return (
      <div className="App">
        <ConfigProvider
             theme={{token: {
                colorPrimary: "#3b2eed"
              }}}
        >
          <TheLayout>
              <BrowserRouter>
                  <Suspense>
                      <Routes>
                          {routes.map(route => {
                              return <Route
                                  key={route.path}
                                  path={route.path}
                                  name={route.name}
                                  element={route.element}
                              />
                          })}
                      </Routes>
                  </Suspense>
              </BrowserRouter>
          </TheLayout>
        </ConfigProvider>
      </div>
  );
}

export default App;

I'm trying to add this button that goes back to the previous page using react-router-dom but I get the above error, and also all the components on my website disappear.


Solution

  • Based on the error I'm guessing you are rendering the Header component in the TheLayout component which is outside the routing context provided by the BrowserRouter.

    Move BrowserRouter higher in the ReactTree such that all react-router-dom routes, links, hooks have the routing context available to them.

    function App() {
      return (
        <BrowserRouter> // <-- render higher in tree
          <div className="App">
            <ConfigProvider
              theme={{
                token: {
                  colorPrimary: "#3b2eed"
                }
              }}
            >
              <TheLayout> // <-- than components that may need routing context
                <Suspense>
                  <Routes>
                    {routes.map(route => (
                      <Route key={route.path} {...route} />
                    ))}
                  </Routes>
                </Suspense>
              </TheLayout>
            </ConfigProvider>
          </div>
        </BrowserRouter>
      );
    }