0

I'm using react version 18 and react-router-dom version 6. I'm having problems using useNavigate outside of functional components. then I did a search and it was recommended to use history.push when outside the component and keep using useNavigate when inside the component. But history push doesn't solve my problem either, history push only change url but not render component.

here are my history settings: /routes/history.js:

import { createBrowserHistory } from 'history';

export const history = createBrowserHistory();

App.js:

import React, {lazy, Suspense, useLayoutEffect, useState} from 'react';
import { BrowserRouter as Router, Route, Routes } from 'react-router-dom';
import PrivateRoute from 'components/PrivateRoute';
import routes from 'routes/mapping-url';
import Loader from 'components/Loader';
import { history } from 'routes/history';

const NotFound = lazy(() => import ('./pages/Errors/404'));

const CustomRouter = ({history, ...props}) => {
  const [state, setState] = useState({
    action: history.action,
    location: history.location
  });

  useLayoutEffect(() => history.listen(setState), [history]);

  return (
    <Router 
      {...props}
      location={state.location}
      navigationType={state.location}
      navigator={history}
    />
  );
};

const App = () => {
  return (
    <CustomRouter history={history}>
      <Routes>
        {routes.map(({path, auth, Component}, key) => 
          auth ? (
            <Route
              key={key}
              exact
              path={path}
              element={<PrivateRoute />}
            >
              <Route path="" element={
                <Suspense fallback={<Loader />}>
                  <Component />
                </Suspense>
              } />
            </Route>
          ):(
            <Route
              key={key}
              exact
              path={path}
              element={<Suspense fallback={<Loader />}>
                <Component />
              </Suspense>}
            />
          )
        )}
        <Route path="*" element={
          <Suspense fallback={<Loader />}>
            <NotFound />
          </Suspense>}/>
      </Routes>
    </CustomRouter>
  );
};

export default App;

This is my list history version:

+-- history@5.3.0
`-- react-router-dom@6.3.0
  +-- history@5.3.0
  `-- react-router@6.3.0
    `-- history@5.3.0
Drew Reese
  • 165,259
  • 14
  • 153
  • 181
  • So where are you trying to use the custom `history` object? What isn't working? – Drew Reese Apr 26 '22 at 07:31
  • Hi thanks @DrewReese for the response. I use it in the function to handle the response from the API, for example, if the status response is 500 then I want to return it to the server error page. `import {history} from 'routes/history';` then I call it at : `if (response.status === 500) { history.push('/500'); }` – Refika Khoirunnissa Apr 26 '22 at 22:17
  • What is the issue? What more precisely isn't working as expected? Your code seems similar to code in answers I've provided [here](https://stackoverflow.com/a/70000286/8690857) and [here](https://stackoverflow.com/a/70012117/8690857) for creating a custom router and history object for use outside React. Can you clarify the issue? Could you create a *running* codesandbox demo that reproduces the issue that we could inspect and debug live? – Drew Reese Apr 26 '22 at 23:36

0 Answers0