So im trying to pass some props from my login component to the payment component with the user's info, to do this I update as shown below:
import React, { Component } from 'react';
import Login from './login';
import { BrowserRouter, Route, Routes } from 'react-router-dom';
import Pay from './payment';
export default class app extends Component {
constructor(props) {
super(props);
this.state = {
LoggedInState: false,
LoggedInUser: [],
SellingProduct: [],
Users: [],
generalproducts: []
}
}
render() {
return (
<BrowserRouter>
<NavBar logged={this.state.LoggedInUser} />
<div className="container-fluid">
<Routes>
<Route path='/' element={<HomePage products={this.generalproducts} />} />
<Route path='/shoppingcart' element={<ShopCart logged={this.state.LoggedInState} paymentHandle={this.onBuyFromCart} products={this.state.generalproducts} />} />
<Route path='/login' element={<Login onLogged={this.onLogInSuccesful} />} />
<Route path='/Payment' element={<Pay ProductInProcess={this.state.SellingProduct} user={this.state.LoggedInUser} />} />
<Route path='/Camera' element={<Cam />} />
<Route path='*' element={<Nomatch />} />
</Routes>
</div>
</BrowserRouter>
)
}
onBuyFromCart = (prod) => {
console.log('in');
this.setState({ SellingProduct: prod });
console.log('dada');
}
onLogInSuccesful = (userlogged) => {
this.setState({ LoggedInState: true, LoggedInUser: userlogged });
console.log('AppLoggedinState', this.state.LoggedInState);
console.log('AppLoggedinuser', this.state.LoggedInUser);
};
componentDidMount = async () => {
var response = await fetch("http://localhost:5000/products");
var ConvertedProducts = await response.json();
this.setState({ generalproducts: ConvertedProducts });
}
}
It works fine from login component to the parent component but when payment tab is displayed I get no values using props, for example:
import React, { Component } from "react";
import { Link } from "react-router-dom";
export default class Pay extends Component {
constructor(props) {
super(props);
this.state = {
productSaled: this.props.ProductInProcess,
info: [],
stored: false
};
}
render() {
return (
<button className="card p-3" onClick={() => { this.onStoredCardClick(); }}>
<div className="img-box">
<img src="https://www.freepnglogos.com/uploads/mastercard-png/file-mastercard-logo-svg-wikimedia-commons-4.png"
alt="" />
</div>
<div className="number">
<label className="fw-bold">{this.props.user.CreditCardnum}</label>
</div>
<div className="d-flex align-items-center justify-content-between">
<small><span className="fw-bold">Expiry date:</span><span>{this.props.user.CreditCardDate}</span></small>
<small><span className="fw-bold">Name:</span><span>{this.props.user.CreditCardName}</span></small>
</div>
</button>
);
}
onStoredCardClick = () => {
this.setState({ stored: true });
console.log('state ', this.state);
console.log(' props', this.props);
}
componentDidMount = () => {
console.log(this.state);
}
}
gives me nothing as seen here:payment info
And login component is:
import React, { Component } from "react";
export default class Login extends Component {
constructor(props) {
super(props);
this.state = { email: "", password: "", message: "" };
}
render() {
return (
<div>
<h4 className="m-1 p-2 border-bottom">Login</h4>
{/* Email starts */}
<div className="form-group form-row">
<label className="col-lg-4">Email:</label>
<input
type="text"
className="form-control"
value={this.state.email}
onChange={(event) => {
this.setState({ email: event.target.value });
}}
/>
</div>
{/* Email ends */}
{/* Password starts */}
<div className="form-group form-row">
<label className="col-lg-4">Password:</label>
<input
type="password"
className="form-control"
value={this.state.password}
onChange={(event) => {
this.setState({ password: event.target.value });
}}
/>
</div>
{/* Password ends */}
<div className="text-right">
{this.state.message}
<button className="btn btn-primary m-1" onClick={this.onLoginClick}>
Login
</button>
</div>
</div>
);
} //end of render
//Executes when the user clicks on Login
onLoginClick = async () => {
var response = await fetch(
`http://localhost:5000/users?id=${this.state.email}&password=${this.state.password}`,
{ method: "GET" }
);
var body = await response.json();
if (body.length > 0) {
//success
var response = await fetch(
`http://localhost:5000/users/${this.state.email}`,
{ method: "GET" }
);
var body = await response.json();
console.log(body);
this.setState({
message: <span className="text-success">Successfully Logged-in</span>,
});
this.props.onLogged(body);
//window.location = '\payment';
} else {
//error
this.setState({
message: (
<span className="text-danger">Invalid login, please try again</span>
),
});
}
};
}
this is the console log form AppState
And this is the console log from Payment
Well, after a couple months I found out that when using window.locaionthe page will refresh al previous values for the props given, therefore, nothing will arrive to the component being loaded. To prevent this I changed to the usage of useNavigate and the hook useContext this solved the shortage of arriving information to the other children components. I am not good with the terminology of react yet so excuse for it.
The log in component now look like this (please focus on the useNavigate and useContext as for it is what solved my error):
import React, { Component, useState, useContext } from "react";
import { UserContext } from "./UserContext";
import { useNavigate } from "react-router-dom";
export default function Login(props) {
const [State, setState] = useState({
Email: "",
password: "",
message: "",
});
const history = useNavigate();
const [GeneralState, setGeneralState] = useContext(UserContext);
let onLoginClick = async () => {
const response1 = await fetch(
`http://localhost:5000/users?id=${State.Email}&password=${State.password}`,
{ method: "GET" }
);
const body1 = await response1.json();
if (body1.length > 0) {
//success
const response = await fetch(
`http://localhost:5000/users/${State.Email}`,
{ method: "GET" }
);
const body = await response.json();
setState({
message: <span className="text-success">Successfully Logged-in</span>,
});
setGeneralState({
...GeneralState,
LoggedInState: true,
LoggedInUser: body,
})
history("/shoppingcart", { replace: true });
} else {
//error
setState({
message: (
<span className="text-danger">Invalid login, please try again</span>
),
});
}
};
return (
<div>
<h4 className="m-1 p-2 border-bottom">Login</h4>
{/* Email starts */}
<div className="form-group form-row">
<label className="col-lg-4">Email:</label>
<input
type="text"
className="form-control"
value={State.Email}
onChange={(event) => {
setState({ ...State, Email: event.target.value });
}}
/>
</div>
{/* Email ends */}
{/* password starts */}
<div className="form-group form-row">
<label className="col-lg-4">password:</label>
<input
type="password"
className="form-control"
value={State.password}
onChange={(event) => {
setState({ ...State, password: event.target.value });
// console.log(GeneralState)
}}
/>
</div>
{/* password ends */}
<div> <a href="/register" style={{ fontSize: 12 }}>No tienes cuenta? Registrate</a></div>
<div className="text-right">
{State.message}
<button className="btn btn-primary m-1" onClick={onLoginClick}>
Login
</button>
</div>
</div>
);
//Executes when the user clicks on Login
}
And the UserContext component, from where useContext takes the info, is this one:
import { createContext } from "react";
export const UserContext = createContext();
As for the other components like app component, shown in the question statement at the start of this thread, it is necessary to also add the useContext statements so that your whole project will work under the same context.
Related
This question relates to React, form refreshing issue (sorry for duplication). But the thing is <form onSumbit={ validation } isn't triggered.
Here's short explanation what I'm trying to achieve as a result. I created a form where the user will enter email and text. When clicking on Submit button - data is sent via SmtpJS. Though, when I enter data - form reloads (form, not the whole page). I tried to control onSubmit event of the form, but it still reloads. Why?
import React, { Component, lazy, Suspense } from 'react';
import './App.css';
import { BrowserRouter, Switch, Route } from 'react-router-dom';
// other components' imports
import { OnlineReception } from './components/OnlineReception/OnlineReception';
export default class App extends Component {
state = {
...
// feedback form
formData: {
host: "smtp.mailtrap.io",
recipient: "recipient#gmail.com", // email is an example here
sender: "",
text: "",
subject: "Feedback",
token: ""
}
}
// send email with data
// from Online Reception's
// component form
/*
sendEmail = () => {
window.Email.send({
Host : this.state.formData.host,
Username : "someUsername", // for local testing
Password : "somePassword", // for local testing
To : this.state.formData.recipient,
From : this.state.formData.sender,
Subject : this.state.formData.subject,
Body : `<html>${this.state.formData.text}</html>`
}).then(
message => alert(message)
)
};
*/
// changing sender & message input values
toggleChangeSender = async (event) => {
await this.setState({
...this.state,
formData: {
host: this.state.formData.host,
recipient: this.state.formData.recipient,
sender: event.target.value,
text: this.state.formData.text,
subject: this.state.formData.subject,
token: this.state.formData.token
}
});
console.log("sender - ", this.state.formData.sender);
}
toggleChangeText = async (event) => {
await this.setState({
...this.state,
formData: {
host: this.state.formData.host,
recipient: this.state.formData.recipient,
sender: this.state.formData.sender,
text: event.target.value,
subject: this.state.formData.subject,
token: this.state.formData.token
}
});
console.log("text - ", this.state.formData.text);
}
render() {
return (
<BrowserRouter>
<div className="App">
...
<Switch>
...
<Route path="/online-reception/" component={
() =>
<OnlineReception
formData={ this.state.formData }
onChangeSenderData={ this.toggleChangeSender }
onChangeTextData={ this.toggleChangeText }
/>
} />
</Switch>
</div>
</BrowserRouter>
);
}
}
OnlineReception component with a form
import React from 'react';
import './css/OnlineReception.css';
export const OnlineReception = (props) => {
let { formData } = { ...props };
const validation = (e) => {
e.preventDefault();
console.log("validation called");
console.log("formData - ", formData);
};
return (
<div className="OnlineReception">
<h3 className="title">
Feedback
</h3>
<form className="feedback"
onSubmit={ validation }
>
<div className="wrapper">
<label>
Email
</label>
<input
type="email"
name="replyto"
className="field"
placeholder="Example: yourname#gmail.com"
autoComplete="off"
value={ formData.sender }
onChange={ props.onChangeSenderData }
/>
<label>
Message
</label>
<textarea
name="message"
className="field text-body"
placeholder="Text here"
value={ formData.text }
onChange={ props.onChangeTextData }
/>
<div className="buttonBox">
<button className="submit"
type="submit"
>
Submit
</button>
</div>
</div>
</form>
</div>
)
};
It seem to be working for me. Though, I just tried it without React Router, just a straight component and it worked fine. I think your issue is you are using the component prop instead of the render prop.
try <Route path="/online-reception/" render={ ...
I am attempting to learn reactjs and I've looked up so many different resources from using react-route to react-route-dom but everything I've tried doesn't work as everything says it does so I am not sure what I am misssing.
I have a class component called LoginForm which renders the form and handles all of the logic for submitting to API and handling the response.
The api request is working and I successfully check that the login is valid, I then want to redirect to another page called dashboard.html.
Below is my component class
import React from 'react'
import * as api from '../JSFuncs/APIManager'
import 'react-router-dom'
class LoginForm extends React.Component {
constructor(props) {
super(props);
this.state = {
username: '',
password: '',
show_notice: false,
error_msg: ''
};
this.handleUsernameChange = this.handleUsernameChange.bind(this);
this.handlePasswordChange = this.handlePasswordChange.bind(this);
this.handleSubmit = this.handleSubmit.bind(this);
}
handleUsernameChange(event) {
this.state.username = event.target.value;
this.setState(this.state);
}
handlePasswordChange(event) {
this.state.password = event.target.value;
this.setState(this.state);
}
handleSubmit(event) {
event.preventDefault();
this.props.history.push("dashboard.html");
this.state.show_notice = true;
this.setState(this.state);
const postArray = {
username: this.state.username,
password: this.state.password
};
let comp = this;
api.sendRequest(postArray, "admin/authenticator.php", "submitLogin").then(function(result){
alert(JSON.stringify(result));
if (result.result === 0)
{
if (result.data === 0) //Login OK
{
comp.history.pushState(null, 'dashboard.html');
//comp.props.history.push('/dashboard.html');
}
comp.setState(comp.state);
}
else
{
comp.state.password = '';
comp.state.error_msg = 'An error occurred with the DB';
comp.setState(comp.state);
}
comp.state.show_notice = true;
comp.setState(comp.state);
})
}
render() {
const style = this.state.show_notice === false ? {display: 'none'} : {};
const { location, history } = this.props
return (
<section className="h-100">
<div className="container h-100">
<div className="d-flex align-items-center justify-content-center h-100">
<div className="d-flex flex-column align-self-center">
<LoginStatus style={style} error_msg={this.state.error_msg} />
<form onSubmit={this.handleSubmit} className='form-horizontal align-self-center'>
<div className='form-group row'>
<label htmlFor='txtUsername' className='col-sm-2 col-form-label'>Username: </label>
<div className='col-sm-9'>
<input type='text' className='form-control' id='txtUsername' value={this.state.username}
placeholder='Your Username' onChange={this.handleUsernameChange}/>
</div>
</div>
<div className='form-group row'>
<label htmlFor='txtPassword' className='col-sm-2 col-form-label'>Password: </label>
<div className='col-sm-9'>
<input type='password' className='form-control' id='txtPassword' value={this.state.password}
placeholder='Your password' onChange={this.handlePasswordChange}/>
</div>
</div>
<div className='formButtonContainer'>
<button className='btn-primary'>Login</button>
</div>
</form>
</div>
</div>
</div>
</section>
);
}
}
class LoginStatus extends React.Component
{
render(){
const className = this.props.error_msg === '' ? 'alert-info' : 'alert-warning';
const msg = this.props.error_msg === '' ? 'You\'ve successfully logged in' : this.props.error_msg;
return(
<div style={this.props.style} className={'alert ' + className}>
{msg}
</div>
)
}
}
export default LoginForm
In the response of handleSubmit I check if the login result is 0 and then I am using comp.history.pushState (comp is declared to be this so its in scope of the promise).
I've tried pushState and push from other examples, but I get the same type of error. I've also tried comp.state.history.push but no luck. I login successfully and show the alert box when I do the history push I get the following:
TypeError: Cannot read property 'push' of undefined
I'm very new to react so apologise if this is a simple answer but I can't seem to get my hand around how this works from everything I've googled.
In your App.js you should manage pages with routes:
import {BrowserRouter, Route, Switch} from "react-router-dom";
import { createBrowserHistory } from "history";
import {LoginForm} from './components/LoginForm';
import {Dashboard} from './components/Dashboard';
const history = createBrowserHistory();
class App extends Component {
constructor(props) {
super(props);
console.log(props)
}
render() {
path="/" is your home or main page
path="/dashboard" is your dashboard
return (
<BrowserRouter>
<div>
<Switch>
<Route path="/" render={(props) => <LoginForm props={history} {...props} /> } exact />
<Route path="/dashboard" render={(props) => <Dashboard props={history} {...props} /> }/>
</Switch>
</div>
</BrowserRouter>
)
then in your LoginForm you can
export class LoginForm extends Component {
constructor(props) {
super(props);
console.log(props)
}
go_dashboard = (e) => {
this.props.history.push("/dashboard");
}
This will then Switch to your Dashboard component.
This question seems like duplicate but it's not. I understand the error and have solved such error number of time but this time I couldn't figure out what's causing infinite loop.
here is code for react component causing the error:
import React, { Component } from 'react';
import { Redirect } from 'react-router-dom';
import PropTypes from 'prop-types';
import './Login.scss';
import axios from 'axios';
import { endPoint } from '../App/path';
import { logIn, isLoggedIn } from '../App/TokenStore';
const re = /^[a-zA-Z0-9_-]{3,15}$/;
class Login extends Component {
constructor() {
super();
this.state = {
username: '',
password: '',
errorMessage: 'Please Login to proceed!',
};
}
onUserNameChange = (e) => {
this.setState({ username: e.target.value });
}
onPasswordChange = (e) => {
this.setState({ password: e.target.value });
}
onFormSubmit = (event) => {
event.preventDefault();
const { username, password } = this.state;
const { history } = this.props;
const isUserNameValid = re.test(String(username).toLowerCase());
if (isUserNameValid) {
axios.post(`${endPoint}/login.json`, { username, password })
.then((response) => {
if (response.status === 200) {
if (response.statusText === 'OK') {
this.setState({
username: '', password: '', errorMessage: '',
});
if (response.config.data) {
console.log(response);
logIn(response.config.data, 'response.config.data.password');
history.push('/dashboard');
} else {
throw new Error();
}
} else {
this.setState({ errorMessage: 'Please enter valid credential!' });
}
}
}).catch((err) => {
if (err.response) {
this.setState({ errorMessage: 'Please enter valid username!' });
} else {
this.setState({ errorMessage: 'Unknown Error!!' });
}
});
} else {
this.setState({ errorMessage: 'Please enter valid username!' });
}
}
render() {
if (isLoggedIn()) {
return <Redirect to="/dashboard" />;
}
const {
username, password, errorMessage,
} = this.state;
return (
<div className="Login">
<form className="Form" onSubmit={this.onFormSubmit}>
<p className="errorMessage">{errorMessage}</p>
<div className="form__group">
<label id="username" className="Label" htmlFor="username">
<i className="fa fa-user" />
<b>Username</b>
</label>
<input
value={username}
onChange={e => this.onUserNameChange(e)}
id="username"
type="username"
placeholder="Your username"
required
/>
</div>
<div className="form__group">
<label id="password" className="Label" htmlFor="password">
<i className="fa fa-key" />
<b>Password</b>
</label>
<input
value={password}
onChange={e => this.onPasswordChange(e)}
id="password"
type="password"
placeholder="Your Password"
required
/>
</div>
<button type="submit" className="Btn">LOGIN</button>
</form>
</div>
);
}
}
Login.propTypes = {
history: PropTypes.shape(),
};
Login.defaultProps = { history: {} };
export default Login;
these are the other function I am using in the above component:
export const logIn = (username, token) => {
sessionStorage.setItem('username', username);
sessionStorage.setItem('loggedIn', true);
sessionStorage.setItem('token', token);
};
export const isLoggedIn = () => Boolean(sessionStorage.getItem('loggedIn'));
here is dashboard component
import React from 'react';
import { NavLink } from 'react-router-dom';
import './Dashboard.scss';
const dashboard = () => (
<div className="container">
<div className="row">
<div className="card col-5 mr-auto ml-auto">
<h5 className="card-header">Lorem ipsum</h5>
<div className="card-body">
<h5 className="card-title">Lorem ipsum</h5>
<p className="card-text">Lorem ipsum</p>
<NavLink to="/dashboard/VRlist" className="btn btn-dashboard">Update/Delete</NavLink>
</div>
</div>
<div className="card col-5 mr-auto ml-auto">
<h5 className="card-header">Lorem ipsum</h5>
<div className="card-body">
<h5 className="card-title">Lorem ipsum</h5>
<p className="card-text">Lorem ipsum</p>
<NavLink to="/dashboard/registration" className="btn btn-dashboard"> Registration</NavLink>
</div>
</div>
</div>
</div>
);
export default dashboard;
here is my main app component
import React from 'react';
import { Switch, Route } from 'react-router-dom';
import Navbar from './Navbar/Navbar';
import Login from './Login/Login';
import Dashboard from './Dashboard/Dashboard';
import { isLoggedIn } from './App/TokenStore';
import VRlist from './VRlist/VRlist';
import NewRegistration from './newRegistration/newRegistration';
import UpdateRegistration from './updateRegistration/updateRegistration';
const App = () => {
if (!isLoggedIn()) {
return (
<div>
<Navbar />
<Route component={Login} />
</div>
);
}
return (
<div>
<Navbar />
<Switch>
<Route exact path="/" component={Login} />
<Route path="/dashboard/VRlist/edit/:id" component={UpdateRegistration} />
<Route path="/dashboard/VRlist" component={VRlist} />
<Route path="/dashboard/registration" component={NewRegistration} />
<Route path="/dashboard" component={Dashboard} />
<Route component={Login} />
</Switch>
</div>
);
};
export default App;
Now when I run the application and do login, this error will happen only for the first time login in the current tab, if I refresh the page the error will go away.
Apparently, I've used react-router and react-router-dom version 5, that's what was causing an infinite render loop while calling an history.push(), however for the rest of the components 'history.push()' was working fine but login page. Though switching over to version 4.3.1 emitted issue completely.
I am trying to redirect a user after login to home page, the redirect happens (this I know because the url changes and I go to a new page), but the content of the page doesn't load. I keep on getting this error
Warning: You tried to redirect to the same route you're currently on: "/index"
Here's my code for Login.js:
import React, { Component } from 'react';
import '../App.css';
import 'whatwg-fetch';
import { connect } from 'react-redux';
import { loginUser } from './../store/actions/loginActions';
import { Redirect, withRouter } from 'react-router-dom';
class Login extends Component {
constructor(props) {
super(props);
this.state = {
Email: '', Password: '', isloggedin: false
};
this.handleChange = this.handleChange.bind(this);
this.handleSubmit = this.handleSubmit.bind(this);
}
handleChange(event) {
this.setState({ [event.target.name]: event.target.value });
}
handleSubmit(event) {
event.preventDefault();
this.props.loginUser(this.state)
}
render() {
const { authError, token } = this.props;
if(token) return <Redirect to="/index" /> // I'm telling it to redirect if the state has a token
return (
<div className="Background">
<Card
title="Login"
style={{ width: 400 }}
>
<Form onSubmit={this.handleSubmit} className="login-form">
<Form.Item>
<Input prefix={<Icon type="user" style={{ color: 'rgba(0,0,0,.25)' }} />} name="Email" type="text" onChange={this.handleChange} />
</Form.Item>
<Form.Item>
<Input prefix={<Icon type="lock" style={{ color: 'rgba(0,0,0,.25)' }} />} type="password" name="Password" onChange={this.handleChange} />
</Form.Item>
<Form.Item>
<Button type="primary" htmlType="submit" disable='notloggedin' className="login-form-button">
Log in
</Button>
</Form.Item>
</Form>
<div>
{ authError ? <p> { authError } </p> : null }
</div>
</Card>
</div>
);
}
}
const mapStateToProps = (state) => {
return {
authError: state.auth.authError,
token: state.auth.token
}
}
const mapDispatchToProps = (dispatch) => {
return {
loginUser: (data) => dispatch(loginUser(data))
}
}
export default withRouter(connect(mapStateToProps, mapDispatchToProps) (Login));
My action is:
export const loginUser = (data) => {
return (dispatch, getState) => {
fetch(url, {
credentials: 'include',
method: 'POST',
headers: headers,
body: JSON.stringify(data)})
.then(res => { if (res.ok) {
return res.json() }
else {
return Promise.reject({
status: res.status,
statusText: res.statusText
})
}
})
.then(function(response) {
dispatch({type: 'LOGIN_USER', value: response.AccessToken });
})
.catch((err) => {
dispatch({type: 'LOGIN_USER_FAILED', err });
})
}
};
and my App.js is
import React, { Component } from 'react';
import { BrowserRouter, Switch, Route } from 'react-router-dom';
import './App.css';
import Login from './components/Login';
import Home from './components/Home';
class App extends Component {
render() {
return (
<div className="App">
<header className="App-header">
<h3 className="App-logo"> App Load </h3>
</header>
<BrowserRouter>
<Switch>
<Route path="/" component={Login} />
<Route path="/index" component={Home} />
</Switch>
</BrowserRouter>
);}}
export default App;
Could anyone please let me know if they see any reason as to why the redirect is working but not loading the page components? I'll really appreciate any pointers.
try to wrap you whole App component into BrowserRouter
I shifted this <Route path="/" component={Login} /> to the bottom of my routes in App.js and it worked.
I am trying to build a simple react login app that navigates to a home page after logging in using this.props.history.push(). Unfortunately, in all of my components this.props is undefined. Here are the relevant portions:
Root:
import React from 'react'
import {
BrowserRouter as Router,
Route
} from 'react-router-dom'
import Login from './views/Login'
import Index from './views/Index'
import Home from './views/Home'
const App = () => {
return(
<Router>
<div>
<Route exact path="/" component={Index}/>
<Route path="/login" component={Login}/>
<Route path="/home" component={Home}/>
</div>
</Router>
)
}
export default App
Index:
import React from 'react'
import Login from './Login'
import Home from './Home'
const Index = () => {
if (localStorage.getItem("username")) {
return(
<Home/>
);
} else {
return (
<Login/>
)
}
}
export default Index
Login:
import React from 'react'
const Login = () => {
let user, pass
const login = e => {
e.preventDefault();
fetch("http://localhost:3000/api/login", {
method: "GET",
headers: {
"user": user.value,
"pass": pass.value
}
})
.then(response => response.json())
.then(function(data) {
if (data.user) {
localStorage.setItem("username", data.user)
this.props.history.push("/");
} else {
console.log("Failed to get user")
}
})
}
return(
<div>
<h1>Login</h1>
<form onSubmit={login}>
<label> Username:
<input type="text" className="form-control col-md-12" ref = {node => user = node}/>
</label>
<label> Password:
<input type="password" className="form-control col-md-12" ref = {node => pass = node}/>
</label>
<br />
<input type="submit" value="Submit" />
</form>
</div>
)
}
export default Login
You also need withRouter from react-router-dom. Your login should look like this:
import React from 'react'
import { withRouter } from 'react-router-dom'
const Login = (props) => {
let user, pass
const login = e => {
e.preventDefault();
fetch("http://localhost:3000/api/login", {
method: "GET",
headers: {
"user": user.value,
"pass": pass.value
}
})
.then(response => response.json())
.then(function(data) {
if (data.user) {
localStorage.setItem("username", data.user)
props.history.push("/");
} else {
console.log("Failed to get user")
}
})
}
return(
<div>
<h1>Login</h1>
<form onSubmit={login}>
<label> Username:
<input type="text" className="form-control col-md-12" ref = {node => user = node}/>
</label>
<label> Password:
<input type="password" className="form-control col-md-12" ref = {node => pass = node}/>
</label>
<br />
<input type="submit" value="Submit" />
</form>
</div>
)
}
export default withRouter(Login)
withRouter is a higher order component. Higher order components are like wrappers that add additional functionality. They take a component as an argument and return a new component; in this case withRouter adds the history props.
Can read more about HOCs here: https://reactjs.org/docs/higher-order-components.html