Reputation: 3237
My App.js
import React, { Component } from 'react';
import './App.css';
import Continue from './components/Continue';
import Login from './components/Login';
import Table from './components/Table';
import Profile from './components/Profile';
import { BrowserRouter,Switch, Route,Redirect } from 'react-router-dom'
function loggedIn() {
return !!localStorage.getItem('token');
}
class App extends Component {
render() {
return (
<div className="App">
<BrowserRouter >
<Switch>
<Route exact path = "/" component ={Login}/>
<Route
exact
path = "/continue"
component = {() =>
loggedIn() ? <Continue /> : <Redirect to="/" />}
/>
<Route
exact
path = "/home"
component={() =>
loggedIn() ? <Table /> : <Redirect to="/" />}
/>
<Route
exact
path = "/profile"
component={() =>
loggedIn() ? <Profile /> : <Redirect to="/" />}
/> </Switch>
</BrowserRouter>
</div>
);
}
}
export default App;
Then from the login form I push to the route /continue
this.props.history.push('/continue');
This happens successfully.
But from Continue when I tried to push to /home same way,
this.props.history.push('/home');
It throws an error
TypeError: this.props.history is undefined
If I remove the loggedIn() make it as login route, then it works.
Need some help to figure out how to send the prop history to other components.
Upvotes: 1
Views: 8363
Reputation: 73
this.props.history
works only if your component is a routed component. See your Login component. It is under the BrowserRouter
and as the part of the Route
. If you need to redirect to another page (component) as a single page application, you need to use useHistory
from react-router-dom
/ react-router
import { useHistory } from 'react-router-dom';
const LNav = (props) => {
let history = useHistory();
return (
<nav className="navbar navbar-expand-lg navbar-dark bg-danger" style={{marginBottom: "5px"}}>
<button className="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarNav" aria-controls="navbarNav" aria-expanded="false" aria-label="Toggle navigation">
<span className="navbar-toggler-icon"></span>
</button>
<div className="collapse navbar-collapse" id="navbarNav">
<ul className="navbar-nav nav-right" id="app-navbar">
<li className="nav-item">
<a className="nav-link" href="javascript:void(0);" onClick={() => history.push(props.add)}><i className="fa fa-plus"></i> Tambah Data</a>
</li>
</ul>
</div>
</nav>
);
};
export default LNav;
Look at that component. That is a functional component (stateless component) and according to the hooks rules, it only works with a function component not a class component.
Upvotes: 1
Reputation: 451
import React, { Component } from 'react';
import './App.css';
import Continue from './components/Continue';
import Login from './components/Login';
import Table from './components/Table';
import Profile from './components/Profile';
import PropTypes from "prop-types";
import { BrowserRouter,Switch, Route,Redirect } from 'react-router-dom'
function loggedIn() {
return !!localStorage.getItem('token');
}
class App extends Component {
render() {
const {location} = this.props.location;
return (
<div className="App">
<BrowserRouter >
<Switch>
<Route exact path = "/" component ={Login}/>
<Route
exact
location={location}
path = "/continue"
component = {() =>
loggedIn() ? <Continue /> : <Redirect to="/" />}
/>
<Route
exact
location={location}
path = "/home"
component={() =>
loggedIn() ? <Table /> : <Redirect to="/" />}
/>
<Route
exact
location={location}
path = "/profile"
component={() =>
loggedIn() ? <Profile /> : <Redirect to="/" />}
/>
</Switch>
</BrowserRouter>
</div>
);
}
}
App.propTypes = {
location: PropTypes.shape({
pathname: PropTypes.string.isRequired,
}).isRequired
};
export default App;
if you don't have the prop-types package installed then use
npm install --save prop-types
Upvotes: 1