Im'm trying to implement a search bar in my nav bar that will bring me a list of cities and according to the selected city it has to update the list of offers in the main page,since the offers is filtered by cities, the thing is, the navbar is one component and the offers is in another component, if I search for a city in my navbar and hit enter, how can the offer component listen to it and make the call to the api based by the searched city? here is my code:
Navbar:
class NavigationBar extends React.Component {
constructor(props) {
super(props);
this.cityoffer = this.cityoffer.bind(this);
}
cityoffer(e) {
e.preventDefault();
this.props.history.push("/home");
console.log("cities");
}
render(){
const { isAuthenticated } = this.props.auth;
const userLinks = (
<form className="form-inline my-2 my-lg-0 ml-auto" onSubmit={this.cityoffer}>
<input className="form-control mr-sm-2" type="search" placeholder="Cidade" aria-label="Search"/>
<button className="btn btn-outline-success my-2 my-sm-0" type="submit">Procurar</button>
</form>
);
const guestLinks = (
<ul className="navbar-nav ml-auto">
<li className="nav-item">
<Link to="/login" className="nav-link">Entrar</Link>
</li>
<li className="nav-item">
<Link to="/signup" className="nav-link">Registrar</Link>
</li>
</ul>
);
return (
<nav className="navbar navbar-expand-lg navbar-dark bg-dark">
<button className="navbar-brand brandbutton" onClick={this.brand}><img src={imglogo} className="imagemNav" alt="logo"/></button>
<button className="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarNavAltMarkup" aria-controls="navbarNavAltMarkup" aria-expanded="false" aria-label="Toggle navigation">
<span className="navbar-toggler-icon"></span>
</button>
<div className="navbar-collapse collapse w-100 order-3 dual-collapse2" id="navbarNavAltMarkup">
{ isAuthenticated ? userLinks : guestLinks }
</div>
</nav>
);
}
}
NavigationBar.propTypes = {
auth: PropTypes.object.isRequired,
logout: PropTypes.func.isRequired
}
function mapStateToProps(state) {
return {
auth: state.auth
};
}
export default withRouter(connect(mapStateToProps, { logout })(NavigationBar));
Offers:
class Anuncios extends React.Component {
constructor(props){
super(props);
this.state = {
city: 2958,
}
}
componentWillReceiveProps = (nextProps) => {
console.log(nextProps)
}
componentDidMount() {
this.props.fetchAnuncios(this.state.city);
}
render() {
return (
<div className="pagemargin">
<AnunciosList anuncios={this.props.anuncios}/>
</div>
);
}
}
Anuncios.propTypes = {
anuncios: PropTypes.array.isRequired,
fetchAnuncios: PropTypes.func.isRequired,
}
function mapStateToProps(state) {
return {
anuncios: state.anuncios
}
}
export default connect(mapStateToProps, {fetchAnuncios, searchCidadesRequestID})(Anuncios);
App:
class App extends Component {
render() {
return (
<div className="App">
<NavigationBar />
<FlashMessagesList/>
</div>
);
}
}
export default App;
routes:
const AppRouter = () => (
<Router>
<div>
<AlertProvider template={AlertTemplate} {...options}>
<App/>
<Switch>
<Route exact path="/" component={Intro}/>
<Route path="/home" component={Home}/>
<Route path="/signup" component={SignUp}/>
<Route path="/login" component={LoginPage}/>
<Route path="/filtrar" component={Filtrar}/>
<Route path="/cupons" component={requireAuth(Cupons)}/>
<Route path="/perfil" component={requireAuth(Perfil)}/>
<Route path="/anuncio/:id" component={AnuncioDetalhes}/>
<Route component={NoMatch}/>
</Switch>
</AlertProvider>
</div>
</Router>
);
like that:
Related
Uncaught TypeError: Cannot read properties of undefined (reading 'pathname')
I have searched about this problem a lot and everywhere I'm getting answer to use to instead of href but I'm already using to
Here is my Code
app.js
import {
BrowserRouter,
Routes,
Route,
Link
} from "react-router-dom";
return (
<>
<Navbar
title="Texter"
aboutus="AboutTextUtils"
toggleMode={toggleMode}
mode={mode}
></Navbar>
<BrowserRouter>
<Routes>
<Route path="/about" element={<About />} />
<Route
path="/"
element= {<Text title="Enter the text below" mode={mode}/>}
/>
</Routes>
</BrowserRouter>
</>
This is navbar where the link tag is
import { Link, Router } from 'react-router-dom';
export default function Navbar(props) {
return (
<Router>
<nav className={`navbar navbar-expand-lg navbar-${props.mode} bg-${props.mode}`}>
<div className="container-fluid">
<a className="navbar-brand" href="/">{props.title}</a>
<button className="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">
<span className="navbar-toggler-icon"></span>
</button>
<div className="collapse navbar-collapse" id="navbarSupportedContent">
<ul className="navbar-nav me-auto mb-2 mb-lg-0">
<li className="nav-item">
<Link className="nav-link active" aria-current="page" to={"/"}>Home</Link> //This is the Link tag
</li>
<li className="nav-item">
<Link className="nav-link" to={"/about"}>{props.aboutus}</Link> //This is the Link tag
</li>
</ul>
<div className={`form-check form-switch text-${props.mode === 'light'?'dark':'light'}`}>
<input className="form-check-input" onClick={props.toggleMode} type="checkbox" role="switch" id="flexSwitchCheckDefault"/>
<label className="form-check-label" htmlFor="flexSwitchCheckDefault">Enable Dark Mode</label>
</div>
</div>
</div>
</nav>
</Router>
)
Issue
You are rendering the Navbar component outside the BrowserRouter and then rendering the Navbar UI into the low-level Router component which has some required props.
See Router
declare function Router(
props: RouterProps
): React.ReactElement | null;
interface RouterProps {
basename?: string;
children?: React.ReactNode;
location: Partial<Location> | string; // <-- required!!
navigationType?: NavigationType;
navigator: Navigator; // <-- required!!
static?: boolean;
}
It's the location being undefined that can't access any pathname property.
Solution
Move the Navbar component into the BrowserRouter so there is a provided router context. Remove the Router in Navbar.
import { Link } from 'react-router-dom';
export default function Navbar(props) {
return (
<nav className={`navbar navbar-expand-lg navbar-${props.mode} bg-${props.mode}`}>
...
</nav>
);
}
import {
BrowserRouter,
Routes,
Route,
Link
} from "react-router-dom";
...
return (
<>
<BrowserRouter>
<Navbar
title="Texter"
aboutus="AboutTextUtils"
toggleMode={toggleMode}
mode={mode}
/>
<Routes>
<Route path="/about" element={<About />} />
<Route
path="/"
element={<Text title="Enter the text below" mode={mode} />}
/>
</Routes>
</BrowserRouter>
</>
);
I am new to react, I am strugging in troubleshooting the error or mistake I am making. When I click on submit button after filling the data the page neither refreshes nor it shows any success message. Can anyone plz help me with this
This is my app.js
import React, { Component } from "react";
import { BrowserRouter as Router, Switch, Route, Link } from "react-router-dom";
import "bootstrap/dist/css/bootstrap.min.css";
import "./App.css";
import AuthService from "./services/auth.service";
import Login from "./components/login.component";
import Register from "./components/register.component";
import Home from "./components/home.component";
import Profile from "./components/profile.component";
import BoardUser from "./components/board-user.component";
import BoardAdmin from "./components/board-admin.component";
class App extends Component {
constructor(props) {
super(props);
this.logOut = this.logOut.bind(this);
this.state = {
showAdminBoard: false,
currentUser: undefined
};
}
componentDidMount() {
const user = AuthService.getCurrentUser();
if (user) {
this.setState({
currentUser: user,
showAdminBoard: user.roles.includes("ROLE_ADMIN")
});
}
}
logOut() {
AuthService.logout();
}
render() {
const { currentUser, showAdminBoard } = this.state;
return (
<Router>
<div>
<nav className="navbar navbar-expand navbar-dark bg-dark">
<Link to={"/"} className="navbar-brand">
Flight Reservation System
</Link>
<div className="navbar-nav mr-auto">
<li className="nav-item">
<Link to={"/home"} className="nav-link">
Home
</Link>
</li>
{showAdminBoard && (
<li className="nav-item">
<Link to={"/admin"} className="nav-link">
Admin
</Link>
</li>
)}
{currentUser && (
<li className="nav-item">
<Link to={"/user"} className="nav-link">
User
</Link>
</li>
)}
</div>
{currentUser ? (
<div className="navbar-nav ml-auto">
<li className="nav-item">
<Link to={"/profile"} className="nav-link">
{currentUser.username}
</Link>
</li>
<li className="nav-item">
<a href="/login" className="nav-link" onClick={this.logOut}>
LogOut
</a>
</li>
</div>
) : (
<div className="navbar-nav ml-auto">
<li className="nav-item">
<Link to={"/login"} className="nav-link">
Login
</Link>
</li>
<li className="nav-item">
<Link to={"/register"} className="nav-link">
Sign Up
</Link>
</li>
</div>
)}
</nav>
<div className="container mt-3">
<Switch>
<Route exact path={["/", "/home"]} component={Home} />
<Route exact path="/login" component={Login} />
<Route exact path="/register" component={Register} />
<Route exact path="/profile" component={Profile} />
<Route exact strict path="/user" component={BoardUser} />
<Route exact strict path="/admin" component={BoardAdmin} />
</Switch>
</div>
</div>
</Router>
);
}
}
export default App;
This is my board-admin.component.js:
import React, { Component } from "react";
import { BrowserRouter as Router, Switch, Route, Link } from "react-router-dom";
import "../Navbar.css";
import AddComponent from "./add-component";
import DeleteComponent from "./delete-component";
import UpdateComponent from "./update-component";
import UserService from "../services/user.service";
export default class BoardAdmin extends Component {
constructor(props) {
super(props);
this.state = {
content: ""
};
}
componentDidMount() {
UserService.getAdminBoard().then(
response => {
this.setState({
content: response.data
});
},
error => {
this.setState({
content:
(error.response &&
error.response.data &&
error.response.data.message) ||
error.message ||
error.toString()
});
}
);
}
render() {
return (
<Router>
<div>
<div className="navbars">
<ul>
<li>
<Link className="link" to={"/add"} >
Add
</Link>
</li>
<li>
<Link className="link" to={"/update"} >
Update
</Link>
</li>
<li>
<Link className="link" to={"/delete"}>
Delete
</Link>
</li>
</ul>
</div>
<div >
<Switch>
<Route exact path="/add" component={AddComponent} />
<Route exact path="/update" component={UpdateComponent} />
<Route path="/delete" component={DeleteComponent} />
</Switch>
</div>
</div>
</Router>
);
}
}
This is my add-component.js:
import React, { Component } from "react";
import FlightsService from "../services/flights.service";
export default class AddComponent extends Component {
constructor(props) {
super(props);
this.onChangeName = this.onChangeName.bind(this);
this.onChangeFrom = this.onChangeFrom.bind(this);
this.onChangeTo = this.onChangeTo.bind(this);
this.onChangeDate = this.onChangeDate.bind(this);
this.onChangeFare = this.onChangeFare.bind(this);
this.saveFlight = this.saveFlight.bind(this);
this.newFlight = this.newFlight.bind(this);
this.state = {
id: null,
name: "",
from: "",
to: "",
date: "",
fare: "",
submitted: false
};
}
onChangeName(e) {
this.setState({
name: e.target.value
});
}
onChangeFrom(e) {
this.setState({
from: e.target.value
});
}
onChangeTo(e) {
this.setState({
to: e.target.value
});
}
onChangeDate(e) {
this.setState({
date: e.target.value
});
}
onChangeFare(e) {
this.setState({
fare: e.target.value
});
}
saveFlight() {
var data = {
name: this.state.name,
from: this.state.from,
to:this.state.to,
date:this.state.date,
fare:this.state.fare
};
FlightsService.create(data)
.then(response => {
this.setState({
id: response.data.id,
name: response.data.name,
from: response.data.from,
to: response.data.to,
date:response.data.date,
fare:response.data.fare,
submitted: true
});
console.log(response.data);
})
.catch(e => {
console.log(e);
});
}
newFlight() {
this.setState({
id: null,
name: "",
from: "",
to: "",
date: "",
fare:"",
submitted: false
});
}
render() {
return (
<div className="submit-form">
{this.state.submitted ? (
<div>
<h4>You submitted successfully!</h4>
<button className="btn btn-success" onClick={this.newFlight}>
Add
</button>
</div>
) : (
<div>
<div className="form-group">
<label htmlFor="title">Name</label>
<input
type="text"
className="form-control"
id="title"
required
value={this.state.name}
onChange={this.onChangeName}
name="title"
/>
</div>
<div className="form-group">
<label htmlFor="description">From</label>
<input
type="text"
className="form-control"
id="description"
required
value={this.state.from}
onChange={this.onChangeFrom}
name="description"
/>
</div>
<div className="form-group">
<label htmlFor="description">To</label>
<input
type="text"
className="form-control"
id="description"
required
value={this.state.to}
onChange={this.onChangeTo}
name="description"
/>
</div>
<div className="form-group">
<label htmlFor="description">Date</label>
<input
type="text"
className="form-control"
id="description"
required
value={this.state.date}
onChange={this.onChangeDate}
name="description"
/>
</div>
<div className="form-group">
<label htmlFor="description">Fare</label>
<input
type="text"
className="form-control"
id="description"
required
value={this.state.fare}
onChange={this.onChangeFare}
name="description"
/>
</div>
<button onClick={this.saveFlight} className="btn btn-success">
Submit
</button>
</div>
)}
</div>
);
}
}
This is my axios related data:
import axios from "axios";
export default axios.create({
baseURL: "http://localhost:8002/api",
headers: {
"Content-type": "application/json"
}
});
This is my service:
import http from "../http-common";
class FlightsService {
create(data) {
return http.post("/flights", data);
}
update(id, data) {
return http.put(`/flights/${id}`, data);
}
delete(id) {
return http.delete(`/flights/${id}`);
}
}
export default new FlightsService();
have you tried annon functions ?
<button onClick={this.saveFlight} className="btn btn-success">
into
<button onClick={()=>{this.saveFlight()}} className="btn btn-success">
you are also binding the function of the click handler to the class of the component. I'm not sure if that is correct (not 100% on react best practices), I haven't dove too deeply into react - but using a master click Handler that handles all click events at the app level has been my strategy when binding functions... that has worked - but I can't guarantee it's not a terrible idea.
Total Newbie in React and most of my learning is done through experimentation.
I have the following components:
App.js
import React, { Component } from 'react';
// Libraries and Utilities
import { BrowserRouter, Switch, Route } from 'react-router-dom';
// Components
import Layout from './components/layout/Layout';
import Home from './components/home/Home';
import Login from './components/login/Login';
class App extends Component {
static displayName = App.name;
render() {
return (
<BrowserRouter basename='/myapp>
<Layout>
<Switch>
<Route path="/" exact component={Home} />
<Route path='/login' component={Login} />
<Route path='/admin' component={Admin} />
</Switch>
</Layout>
</BrowserRouter>
);
}
}
export default App;
Layout.js
import React, { Component } from 'react';
import NavMenu from '../navigation/NavMenu';
class Layout extends Component {
render() {
return (
<div className="container-fluid">
<div className="row">
<NavMenu />
</div>
<div className="main layout">
{this.props.children}
</div>
<div className="row">
<Footer />
</div>
</div>
);
}
};
export default Layout;
NavMenu.js
import React, { Component } from 'react';
import { NavLink } from "react-router-dom";
import logo from '../../assets/logo.svg';
class navigation extends Component {
constructor(props) {
super(props)
this.state = {
loggedIn: false
}
}
render() {
return (
<div className="row">
<nav className="navbar navbar-expand navbar-dark bg-primary fixed-top">
<a className="navbar-brand" href="/">
<img src={logo} width="250" height="70" alt="" />
</a>
<div className="collapse navbar-collapse">
<ul className="navbar-nav mr-auto">
<li className="nav-item" to={'/'}>
<NavLink exact={true} className="navbar-brand" activeClassName='active' to='/'>Home</NavLink>
</li>
<li className="nav-item" to={'/admin1'}>
<NavLink exact={true} className="navbar-brand" activeClassName='active' to='/admin1'>Admin 1</NavLink>
</li>
<li className="nav-item" to={'/admin2'}>
<NavLink exact={true} className="navbar-brand" activeClassName='active' to='/admin1'>Admin 2</NavLink>
</li>
</ul>
<ul className="navbar-nav">
<li className="nav-item">
<NavLink exact={true} className="navbar-brand" activeClassName='active' to='/login'>
<i className="fa fa-sign-in" aria-hidden="true"></i>
</NavLink>
</li>
</ul>
</div>
</nav>
</div>
)
};
};
export default navigation;
Login .js
import React, { Component } from 'react';
class login extends Component {
constructor(props) {
super(props)
this.state = {
loginModel: {
UserName: '',
Password: ''
}
}
this.handleInputChange = this.handleInputChange.bind(this)
this.handleSubmit = this.handleSubmit.bind(this)
}
handleInputChange(event) {
const target = event.target
const value = target.type === 'checkbox' ? target.checked : target.value
const name = target.name
this.setState(prevState => ({
loginModel: {
...prevState.loginModel,
[name]: value
}
}))
}
handleSubmit(event) {
// At This Stage, I perform an API Call (via axios) and I get the Response Data.
const url = 'some url'
axios.post(url, this.state.loginModel).then((response) => {
if (response.status === 200) {
// Get token from response to be used in authenticated api calls.
const responseData = response.data
let authToken = responseData.token
console.log('authToken', authToken)
swal({
title: "My Application",
text: "Logon Successful.",
icon: "success"
}).then((value) => {
// Go to the Admin Home.
const path = '/admin'
this.props.history.push(path);
})
}
}, (err) => {
console.log(err.response)
const msg = err.response.data.message
const icon = err.response.data.icon
swal({
title: "My Application",
text: msg,
icon: icon
})
})
)
event.preventDefault();
}
componentDidMount() {
}
render() {
return (
<form className="form-signin" onSubmit={this.handleSubmit} >
<h3>Sign In</h3>
<div className="form-group">
<label>Username</label>
<input type="text" className="form-control" autoComplete="off"
id="input-username" name="UserName"
value={this.state.loginModel.UserName}
onChange={this.handleInputChange}
placeholder="Enter Username" />
</div>
<div className="form-group">
<label>Password</label>
<input type="password" className="form-control" autoComplete="off"
id="input-password" name="Password"
value={this.state.loginModel.Password}
onChange={this.handleInputChange}
placeholder="Enter Password" />
</div>
<button type="submit" className="btn btn-primary btn-block">Submit</button>
</form>
)
}
}
export default login;
Home.js
import React from 'react';
import { NavLink } from "react-router-dom";
const home = (props) => {
return (
<div className="container-fluid">
<div className="fill">
<div className="row">
<div className="col-md-4 col-sm-12">
<div className="card">
<div className="card-body flex-fill">
<h5 className="card-title">Info 1</h5>
<p className="card-text">
Details about Info 1
</p>
</div>
<div className="card-footer">
<NavLink exact={true} className="btn btn-primary btn-block" to='/info1'>Start</NavLink>
</div>
</div>
</div>
<div className="col-md-4 col-sm-12">
<div className="card">
<div className="card-body flex-fill">
<h5 className="card-title">Info 2</h5>
<p className="card-text">
Details about Info 2
</p>
</div>
<div className="card-footer">
<NavLink exact={true} className="btn btn-info btn-block" to='/info2'>Browse</NavLink>
</div>
</div>
</div>
<div className="col-md-4 col-sm-12">
<div className="card">
<div className="card-body flex-fill">
<h5 className="card-title">Info 3</h5>
<p className="card-text">
Details about Info 3
</p>
</div>
<div className="card-footer">
<NavLink exact={true} className="btn btn-success btn-block" to='/info3'>View</NavLink>
</div>
</div>
</div>
</div>
</div>
</div>
);
};
export default home;
My approach is quite simple. The application shows the Home component on initial load.
In the Navmenu, I have a link that navigates me to the Login screen.
In the Login screen, I have a login form where I am able to validate the user name and password via an API call.
I have multiple questions as I am still learning, but adding them here altogether as I feel it is all related.
Questions:
In my NavMenu component, I want to hide the admin1 and admin2 when on
initial load, and show it when the login is successful in the Login
component.
I want to prevent user from going to the route /admin1 and
/admin2 unless they are logged in. I am trying to read Protected
Routes but I am unable to get the hang of it as of yet.
In my Login screen, after successful login, one of the return value of the API
call is an API Key I can use for authorized calls. How can I make
that available such that I can access it from anywhere I perform an
API call.
I hope I provided enough context on what I am trying to achieve here. I know I need to brush up further my skills on how data communication between React happens.
Update: Been reading about Hooks, but I am unsure how to implement it here. Would I need to convert my JS files to use functional approach rather than class structure (ES6)?
Gracias.
I use redux for checking if use if logged in or not.
So when app start before show anything I check this.
and then I have privateRoute.
import React from "react";
import { Redirect, Route } from "react-router-dom";
import { useSelector } from "react-redux";
function PrivateRoute({ component: Component, ...props }) {
const isAuthenticated = useSelector(state => state.User.isLogin);
return (
<Route
render={props =>
isAuthenticated ? (
<Component {...props} />
) : (
<Redirect
to={{
pathname: "/login",
state: { from: props.location }
}}
/>
)
}
{...props}
/>
);
}
export default PrivateRoute;
and define IsAuthenticated component to redirect home page if user is already logged in:
import React from "react";
import { Redirect, Route } from "react-router-dom";
import { useSelector } from "react-redux";
function IsAuthenticated({ component: Component, ...props }) {
const isAuthenticated = useSelector(state => state.User.isLogin)
return (
<Route
{...props}
render={props =>
!isAuthenticated ? (
<Component {...props} />
) : (
<Redirect
to={{
pathname: "/",
state: { from: props.location }
}}
/>
)
}
/>
);
}
export default IsAuthenticated;
and define my routes here if user must authenticated to see them:
<Router>
<Switch>
{privateRoutes.map(({ path, component: Component }, idx) => (
<PrivateRoute
key={idx}
exact
path={path}
component={() => (
<SideNav>
<Component />
</SideNav>
)}
/>
))}
<IsAuthenticated exact path="/login" component={LoginPage} />
</Switch>
</Router>
here I use SideNav in my pages, you can use redux state in your Navbar component and with checking that you can show or hide whatever you want.
Or you can define two layout for your two types of your pages.
If you don't want to use redux, you can define state in App.js and pass it to your component or use react context.
I hope I helped you in your question.
Below is the code of the react component of my project. this.props.isAuthenticatedis working when I return the component but when I print this.props.isAuthenticated inside componentDidMount I am getting false(print logout). How do I get authentication status true or false in react component?
I have added redux already and login logout working fine.
import React, { Component } from "react";
import { NavLink, Route, withRouter } from "react-router-dom";
import NewsListView from "../Container/NewsListView";
import StatsView from "../Container/StatsView";
import VotingView from "../Container/VotingView.js";
import Rightsidebar from "../Container/rightsidebar";
import Footer from "./footer";
import Loginform from "../Container/loginform";
import SignUp from "../Container/SignUp";
import { connect } from "react-redux";
import * as actions from "../Store/actions/auth";
class Header extends React.Component {
componentDidMount() {
{
this.props.isAuthenticated ? console.log("login") : console.log("logout");
}
}
render() {
return (
<div>
<nav className="navbar navbar-inverse">
<div className="container-fluid">
<div className="navbar-header">
<button
type="button"
className="navbar-toggle"
data-toggle="collapse"
data-target="#myNavbar"
>
<span className="icon-bar" />
<span className="icon-bar" />
<span className="icon-bar" />
</button>
<NavLink className="navbar-brand" to="/">
Save4thPillar
</NavLink>
</div>
<div className="collapse navbar-collapse" id="myNavbar">
<ul className="nav navbar-nav">
<li>
<NavLink to="/" className="navlink">
Home
</NavLink>
</li>
<li>
<NavLink to="/news" className="navlink">
news
</NavLink>
</li>
<li>
<NavLink to="/stats" className="navlink">
stats
</NavLink>
</li>
{this.props.isAuthenticated ? (
<li>
<NavLink
to="/logout"
onClick={this.props.logout}
className="navlink"
>
Logout
</NavLink>
</li>
) : (
<li>
<NavLink to="/login" className="navlink">
Login
</NavLink>
</li>
)}
</ul>
</div>
</div>
</nav>
<div className="container">
<div className="row">
<div className="col-md-8">
<Route exact path="/" component={VotingView} {...this.props} />
<Route exact path="/news" component={NewsListView} />
<Route exact path="/stats" component={StatsView} />
<Route exact path="/login" component={Loginform} />
<Route exact path="/signup" component={SignUp} />
</div>
<div className="col-md-4">
<Rightsidebar />
</div>
<div />
</div>
<Footer />
</div>
</div>
);
}
}
const mapDispatchToProps = dispatch => {
return {
logout: () => dispatch(actions.logout())
};
};
export default withRouter(
connect(
null,
mapDispatchToProps
)(Header)
);
You should implement the Header component's constructor. to use props in lifecycles
class Header extends React.Component {
componentDidMount() {
{
this.props.isAuthenticated ? console.log("login") : console.log("logout");
}
constructor(props){
super(props);
}
[...]
}
Hi I am pretty new to ReactJS, I am trying to move to the login page when Logout is clicked, the function is getting executed but it wont redirect to the login page. I don't know how to do it. I have tried using this.props.history.push but that is also not working. I have also tried using Redirect to="/login" in the fakeAuth.signout function.
import React, { Component } from 'react';
import './App.css';
import GetTodo from './component/getTodo.js';
import AddTodo from './component/addTodo.js';
import Login from './component/login.js';
import {BrowserRouter as Router,Switch,Route,Link,Redirect} from
'react-router-dom';
export const fakeAuth = {
isAuthenticated: false,
authenticate(cb) {
this.isAuthenticated = true;
},
signout(cb) {
this.isAuthenticated = false;
}
}
const PrivateRoute = ({ component: Component, ...rest }) => (
<Route {...rest} render={(props) => (
fakeAuth.isAuthenticated === true
? <Component {...props} />
: <Redirect to='/login' />
)} />
)
class App extends Component {
constructor(props){
super(props);
this.newsignout=this.newsignout.bind(this);
}
newsignout(){
fakeAuth.signout();
localStorage.clear();
<Redirect to="/login" />
}
render() {
return (
<Router>
<div className='App'>
<nav className="navbar navbar-expand-lg navbar-light bg-light">
<div className="collapse navbar-collapse">
<div className="navbar-nav">
<div className="nav-item nav-link"><Link to={'/'}>GET TODO LIST</Link></div>
<div className="nav-item nav-link"><Link to={'/add'}>ADD TODO</Link></div>
<div className="nav-item nav-link"><Link to={'/login'}>LOGIN</Link></div>
<div className="nav-item nav-link "><div className="LogOut" onClick={()=>this.newsignout()}>LOGOUT</div></div>
</div>
</div>
</nav>
<Switch>
<PrivateRoute exact path='/' component={GetTodo} />
<PrivateRoute path='/add/:id' component={AddTodo} />
<PrivateRoute exact path='/add' component={AddTodo} />
<Route path='/login' component={Login}/>
</Switch>
</div>
</Router>
);
}
}
export default App;
You can use "State" and chang this page without Redirect.
For example:
class MyComponent extends React.Component {
constructor(){
super();
state = {
isLogin: true
}
}
newsignout(){
this.setState({ isLogin: false });
}
render () {
const { isLogin } = this.state;
if (!isLogin) {
return <LoginPage />; // for example
}
return <RenderYourForm/>; // other code
}
this is working
<div className="nav-item nav-link "><Link to={'/login'} className="LogOut" onClick={()=>this.newsignout()}>LOGOUT</Link></div>