0

I have a functional component with a react-router.
Working fine when using <Link ... /> but I want to redirect on some event.
The problem is that props.history is undefined.


function App(props) {
  const onClick = () => {
    console.log(props.history);
    //props.history.push("/about");
  };
  return (
    <div className="App">
      <BrowserRouter>
        <Link to="/about">About</Link> <br />
        <button onClick={onClick}>
          <b>onclick redirect</b>
        </button>
        <Route path="/about" component={About} />
      </BrowserRouter>
    </div>
  );
}

https://codesandbox.io/s/react-router-demo-o6s89

How can I redirect programmatically?

Thanks

Vencovsky
  • 28,550
  • 17
  • 109
  • 176
SexyMF
  • 10,657
  • 33
  • 102
  • 206
  • 1
    Possible duplicate of [Programmatically navigate using react router](https://stackoverflow.com/questions/31079081/programmatically-navigate-using-react-router) – Vencovsky Nov 25 '19 at 15:07

2 Answers2

2

Wrap you App component in withRouter HOC and move BrowserRouter to AppContainer component. This should work.

import { Route, Link, BrowserRouter, withRouter } from "react-router-dom";

function App(props) {
  const onClick = () => {
    console.log(props.history);
    props.history.push("/about");
  };
  return (
    <div className="App">
      <Link to="/about">About</Link> <br />
      <button onClick={onClick}>
        <b>onclick redirect</b>
      </button>
      <Route path="/about" component={About} />
    </div>
  );
}

const AppWithRouter = withRouter(App);

const AppContainer = () => {
  return (
    <BrowserRouter>
      <AppWithRouter />
    </BrowserRouter>
  );
};

const rootElement = document.getElementById("root");
ReactDOM.render(<AppContainer />, rootElement);
Murli Prajapati
  • 8,833
  • 5
  • 38
  • 55
  • Thanks, what happens when it comes to sub-component? history should be passed manually to each subcomponent? if so, that's crazy... thanks – SexyMF Nov 25 '19 at 15:21
  • No...wrap sub components in withRouter HOC. Or use `useHistory` hook if you are using the latest version of react-router-dom. https://reacttraining.com/react-router/web/api/Hooks/usehistory – Murli Prajapati Nov 25 '19 at 15:22
0

The reason that this.props.history is undefined is because you can only acces this prop in a route that is set. The prop is passed to all the routes. If what you want is redirecting the user from the app component, then you should use the Link component.

Edit react-router-demo

import React from "react";
import ReactDOM from "react-dom";
import { Route, Link, BrowserRouter } from "react-router-dom";
import "./styles.css";
import About from "./components/About";

const App = () => (
  <div className="App">
    <BrowserRouter>
      <Link path="/about" to="about">About</Link> 
      <Route path="/about" component={About} />
    </BrowserRouter>
  </div>
);

const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);
import React from "react";

const About = props => {
  const onClick = () => {
    console.log(props);
    props.history.push("/about");
  };

  return (
    <div>
      <h1>About Us</h1>
      <button onClick={onClick}>
        <b>onclick redirect</b>
      </button>
    </div>
  );
};

export default About;
Jurrian
  • 850
  • 6
  • 20