How to access BrowserRouter history outside of BrowserRouter?

Viewed 128

Below is my code snippet simplified. (using react-router-v5) My question is how to get access to BrowserRouter's history in the logout_Handler(), given that I am "outside" BrowserRouter?

I've seen this answer How to access history object outside <Route /> in React Router v4 , but there is also a comment which applies to my case: "When I try to use "withRouter" as shown here I get the error

You should not use <Route> or withRouter() outside a <Router>

which is exactly what I get, if I try to use withRouter at the App.js level.

// App.js

function App(props) {

    const logout_Handler = (e) => {

        localStorage.removeItem("app-tokenObj");

        // how to get the history from BrowserRouter to redirect?!
        //history.push("/login") ?? NO IDEA ??

    }

    return (
        <BrowserRouter>
            <nav>
                <h3>My Supa Dupa App</h3>

                <Link to="/">Home Page</Link>
                <Link to="/admin">Admin Page</Link>
                <button type="button" onClick={logout_Handler}>Logout</button>
            </nav>
            
            <hr/>
            <Switch>
                <Route exact path="/" component={Home} />
                <Route path="/link1" component={Comp1} />
                <Route path="/link2" component={Comp1} />
                <Route path="/login" component={Login} />
                <Route path="/signup" component={Signup} />
            </Switch>

        </BrowserRouter>
    )
}
1 Answers

If you are trying to access parts of a routing context in the App component then the router providing the context needs to be higher in the ReactTree. The solution is simple. Move BrowserRouter higher than App in your apps code. Wrapping App in the BrowserRouter would be sufficient enough for this.

Example index.js

ReactDOM.render(
  ...
    <BrowserRouter>
      <App />
    </BrowserRouter>
  ...,
  root,
);

App

The App component now has a routing context available. While you could use the withRouter Higher Order Component, using the useHistory hook would be simpler.

import { Link, Route, useHistory } from 'react-router-dom';

function App(props) {
  const history = useHistory();

  const logout_Handler = (e) => {
    localStorage.removeItem("app-tokenObj");
    history.push("/login");
  }

  return (
    <>
      <nav>
        <h3>My Supa Dupa App</h3>

        <Link to="/">Home Page</Link>
        <Link to="/admin">Admin Page</Link>
        <button type="button" onClick={logout_Handler}>Logout</button>
      </nav>
            
      <hr/>
      <Switch>
        <Route path="/link1" component={Comp1} />
        <Route path="/link2" component={Comp1} />
        <Route path="/login" component={Login} />
        <Route path="/signup" component={Signup} />
        <Route path="/" component={Home} />
      </Switch>
    </>
  );
}
Related