App.js
This is the event handling button click:
this.handleClick = this.handleClick.bind(this); handleClick(e) { debugger; e.preventDefault(); this.context.router.history.push('/HomePage'); } <button onClick={this.handleClick}>Navigate </button> TypeError: Cannot read property 'history' of undefined
I installed this using: npm install prop-types --save
It's not working.
35 Answers
To verify why is not working you can console.log() your props, and you will see that history won't appear, so then how you can fix that? Well, it's easy, you have two ways:
withRouter HOC
Using
withRouterYou can get access to the history object’s properties and the closest 's match via thewithRouterhigher-order component.withRouterwill pass updated match, location, and history props to the wrapped component whenever it renders.
props.history.push('/path') Example:
import React from 'react'; import {withRouter} from 'react-router-dom'; function App({ history }) { return ( <div> <button onClick={() => history.push('/signup')}> Signup </button> </div> ); } export default withRouter(App) <Redirect /> component
Rendering a
<Redirect>will navigate to a new location. The new location will override the current location in the history stack, like server-side redirects (HTTP 3xx) do.
Example:
import React from 'react'; import {Redirect} from 'react-router-dom'; class Register extends React.Component { state = { toDashboard: false } handleSubmit = (user) => { saveUser(user).then(() => this.setState(() => ({ toDashboard: true }))); } render() { if (this.state.toDashboard) { return <Redirect to='/dashboard' /> } return ( <div> <h1>Register</h1> <Form onSubmit={this.handleSubmit} /> </div> ) } } I hope this help you folks!
1JSX
<Link to="/home">Homepage</Link>
If you want to use it in jsx. <Link> compiles down to <a> tag in HTML so just treat it like that
Programmatically
this.props.history.push('/home');
The reason why history is undefined is you might have the main routing page set up wrong
// app.js import { BrowserRouter, Route, } from 'react-router-dom' import UserList from './path/to/UserListComponent' class App extends Component { ... render() { return ( <BrowserRouter> ... <Route path="/users" component={UserList}/> ... </BrowserRouter> ) } } Do something like this
0You have a two way
use Redirect from react-router:
In your handleClick method set a state and check in the render method and if that's true Redirect like the following:
<Redirect to="/HomePage" /> And another way is using window.location like the following:
window.location = '/HomePage'; 3I know it's late but I want to share something, react-router-dom has been updated.
<BrowserRouter> <Routes> <Route path="/" element={<App/>} /> <Route path="/new-page" element={<Home/>} /> </Routes> </BrowserRouter> like components to element and history.push('/home') to navigate('/home')
const navigate = useNavigate() navigate('/new-page'{ state: pass-data } ) React Router v6 implements useNavigate (docs).
import { useNavigate } from 'react-router-dom'; let navigate = useNavigate(); navigate('/myOtherPath');