Cannot read property 'push' of undefined on the login page - javascript

I'm doing a login page with JWT and trying to redirect the page once log in to the home using this.props.history.push("/") but I get this typeError: Cannot read property 'push'of undefined. I don't know what I am doing wrong.
class Login extends Component {
constructor(props) {
super(props);
this.state = {
email: "cihemzine#gmail.com",
password: "test",
};
}
handleChange = (e) => {
this.setState({
[e.target.name]: e.target.value,
});
};
login = () => {
const { email, password} = this.state;
axios("/users/login", {
method: "POST",
data: {
email,
password
},
})
.then((response) => {
localStorage.setItem('token', response.data.token);
console.log(response.data);
this.props.history.push("/");
})
.catch((error) => {
console.log(error);
});
};
render() {
return (
<div>
<div className="container">
<input value={this.state.email} onChange={this.handleChange} className="form-control mb-2 mt-4"name="email" type="text"placeholder="Your email" />
<input value={this.state.password} onChange={this.handleChange} className="form-control mb-2"name="password" type="password" placeholder="Your password" /><br></br>
<button onClick={this.login}className="text-center btn btn-light">LOGIN</button>
</div>
</div>
)
}
}
export default Login;

If you have nothing like 'history, match etc' in your props you need to check that you use your login component as Route
<Route path ='' component={Login} />
If you don't use Login in such way and can't for some reasons.
You can use HOC or hook for you component to add history to your component.
import { useHistory } from "react-router-dom"
or
import { withRouter } from "react-router";

Related

How to update state with redux

I'm trying to build simple login form (data for authorization from API). So I have Slice for auth here is code :
auth.js
import { createSlice } from '#reduxjs/toolkit'
export const authSlice = createSlice({
name: 'auth',
initialState: {
isLoggedIn: false,
token: null,
role: null
},
reducers: {
logIn: (state) => {
state.isLoggedIn = true
},
role:(state, action) =>{
state.role = action.payload
},
token:(state, action) =>{
state.token = action.payload
},
logOut: (state) => {
state.isLoggedIn = false
},
},
})
export default authSlice.reducer;
export const { logIn, logOut, role, token } = authSlice.actions
authService.js :
import axios from 'axios';
import { api } from '../api/index'
export function authenticateUser(username, password) {
axios
.post(api + 'login', {username, password})
.then(res => {
console.log(res.headers.authorization)
})
}
LoginForm.js
import React, { Component } from 'react';
import { Form, Col, Button } from 'react-bootstrap';
import { IoMdLogIn } from "react-icons/all";
import { authenticateUser } from '../services/authService'
export default class LoginForm extends Component{
constructor(props) {
super(props);
this.state = this.initialState;
this.credentialsChange = this.credentialsChange.bind(this);
this.userLogin= this.userLogin.bind(this);
}
initialState = {
username: '', password: ''
}
userLogin = (e) => {
e.preventDefault();
authenticateUser(this.state.username, this.state.password);
this.setState( () => this.initialState)
}
credentialsChange = e => {
this.setState({
[e.target.name]:e.target.value
});
}
render(){
const {username, password} = this.state;
return(
<Form onSubmit={this.userLogin} id="loginFormId">
<Form.Row>
<Form.Group as={Col} controlId="formGridCountry">
<Form.Label>Username</Form.Label>
<Form.Control required autoComplete="off"
type="text" name="username"
value={username}
onChange={this.credentialsChange}
className={"bg-light"}
placeholder="Username" />
</Form.Group>
</Form.Row>
<Form.Row>
<Form.Group as={Col} controlId="formGridZipCode">
<Form.Label>Password</Form.Label>
<Form.Control required autoComplete="off"
type="password" name="password"
value={password}
onChange={this.credentialsChange}
className={"bg-light"}
placeholder="Password" />
</Form.Group>
</Form.Row>
<Button type="submit" variant="success">
<IoMdLogIn />
</Button>
</Form>
);
}
}
What I'm trying to reach is : I want to update state isLoggedIn : true after calling function authenticateUser.
I've tried to use const dispatch = useDispatch() and then calling dispatch(logIn()) but it's throwing error.
Where should I call dispatcher to update state?
You need to call the dispatcher in your AuthService.js in the api response.
Check the response, if it is ok, store it. If your redux is well implemented, it will work.
axios
.post(api + 'login', {username, password})
.then(res => {
console.log(res.headers.authorization)
//Call it here, or create a function and call it here.
})
}
If it doesn't work, please share the error with us

Redirect after login React.js

i've been trying since days to redirect my user after login to the home creating a callback function in my App.js and sending it as props to the login class component throught a loginregisterpage class component, but this doesn't work, can someone have a look on it and tell me what i;m missing out?
Thank you my code look like this
App.js
import React from 'react'
import { BrowserRouter as Router, Switch, Route } from 'react-router-dom'
import { HomePage } from './Pages/HomePage/HomePage'
import { LoginRegisterPage } from './Pages/LoginRegisterPage/LoginRegisterPage'
import 'bootstrap/dist/css/bootstrap.min.css'
export class App extends React.Component {
constructor(props) {
super(props);
this.state = {
authenticated: false,
}
this.handleSuccess = this.handleSuccess.bind(this);
}
handleSuccess = (data) => {
this.props.history.push("/")
}
render() {
return (
<Router>
<Switch>
<Route exact path="/">
<HomePage />
</Route>
<Route exact path="/login-register">
<LoginRegisterPage onLoginSuccess={this.handleSuccess} />
</Switch>
</Router>
)
}
}
LoginRegisterPage class component
class LoginPage extends React.Component {
constructor(props) {
super(props);
this.state = {
username: '',
password: '',
accessToken: '',
authenticated: ''
};
this.handleChangeUsername = this.handleChangeUsername.bind(this);
this.handleChangePassword = this.handleChangePassword.bind(this);
}
handleChangeUsername(event) {
this.setState({
username: event.target.value
})
}
handleChangePassword(event) {
this.setState({
password: event.target.value
})
}
handleClick(event) {
var apiBaseUrl = "https://myapi.com/auth/"
const payload = {
method: "POST",
headers: {
'Content-Type': 'application/json; charset=utf-8'
},
body: JSON.stringify({
'username': this.state.username,
'password': this.state.password
})
};
const { username, password } = this.state;
if (username && password) {
fetch(apiBaseUrl + 'login', payload)
.then((response) => {
if (response.status === 200) {
alert("Logged In! You'll be redirected on Home")
return response.json()
} else {
return alert("wrong pass")
}
}).then((data) => {
this.setState({
accessToken: data.accestToken,
authenticated: data.authenticated
});
localStorage.setItem('accessToken', data.accessToken);
if (data.authenticated === true) {
console.log(this.props)
this.props.onLoginSuccess(data)
}
})
.catch((err) => console.log(err));
} else {
alert("Cannot be Empty")
}
}
render() {
return (
<div>
<div className="form">
<div>
<div className="form-input">
<div >
<div className="userData">
<span>
<img
src={UserIcon}
/>
</span>
<input
autocomplete="off"
type="text"
name="username"
placeholder="Username"
value={this.state.username}
onChange={this.handleChangeUsername}
/>
</div>
<div className="userData">
<span>
<img
src={PasswordIcon}
/>
</span>
<input
autocomplete="off"
type="password"
name="password"
placeholder="Password"
value={this.state.password}
onChange={this.handleChangePassword}
/>
<p style={(this.state.username && this.state.password) ? { display: 'none' } : { display: 'block' }}> Must fill all the form!</p>
</div>
</div>
</div>
</div>
</div>
<div className="form-footer">
<img
src={Btn}
onClick={(event) => this.handleClick(event)}
/>
</div>
</div>
);
}
}
LoginPage class component
class LoginPage extends React.Component {
constructor(props) {
super(props);
this.state = {
username: '',
password: '',
accessToken: '',
authenticated: ''
};
this.handleChangeUsername = this.handleChangeUsername.bind(this);
this.handleChangePassword = this.handleChangePassword.bind(this);
}
handleChangeUsername(event) {
this.setState({
username: event.target.value
})
}
handleChangePassword(event) {
this.setState({
password: event.target.value
})
}
handleClick(event) {
var apiBaseUrl = "https://movies-app-siit.herokuapp.com/auth/"
const payload = {
method: "POST",
headers: {
'Content-Type': 'application/json; charset=utf-8'
},
body: JSON.stringify({
'username': this.state.username,
'password': this.state.password
})
};
const { username, password } = this.state;
if (username && password) {
fetch(apiBaseUrl + 'login', payload)
.then((response) => {
if (response.status === 200) {
alert("Logged In! You'll be redirected on Home")
return response.json()
} else {
return alert("wrong pass")
}
}).then((data) => {
this.setState({
accessToken: data.accestToken,
authenticated: data.authenticated
});
localStorage.setItem('accessToken', data.accessToken);
if (data.authenticated === true) {
console.log(this.props)
this.props.onLoginSuccess(data)
}
})
.catch((err) => console.log(err));
} else {
alert("Cannot be Empty")
}
}
render() {
return (
<div>
<div className="form">
<div>
<div className="form-input">
<div >
<div className="userData">
<span>
<img
src={UserIcon}
/>
</span>
<input
autocomplete="off"
type="text"
name="username"
placeholder="Username"
value={this.state.username}
onChange={this.handleChangeUsername}
/>
</div>
<div className="userData">
<span>
<img
src={PasswordIcon}
/>
</span>
<input
autocomplete="off"
type="password"
name="password"
placeholder="Password"
value={this.state.password}
onChange={this.handleChangePassword}
/>
<p style={(this.state.username && this.state.password) ? { display: 'none' } : { display: 'block' }}> Must fill all the form!</p>
</div>
</div>
</div>
</div>
</div>
<div className="form-footer">
<img
src={Btn}
onClick={(event) => this.handleClick(event)}
/>
</div>
</div>
);
}
}
If you're using React Router you can use the Redirect component:
import { Redirect } from 'react-router-dom';
export default function PrivateRoute () {
if (notLoggedIn()) {
return <Redirect to="/login"/>;
}
// return your component
}
But if you're not inside a render function (i.e. you're in a submit callback) or you want to rewrite browser history, use the useHistory hook (note: hooks work only in function components, not class components)
import { useHistory } from 'react-router-dom';
const history = useHistory();
// After your login action you can redirect with this command:
history.push('/otherRoute');
Issue
App is defined outside the Router component so it has no history prop function to call to do any navigation.
Solution
Have the LoginRegisterPage component navigate upon successful authentication. It will need to access the history object of the nearest Router context. Normally this is achieved by consuming passed route props from the Route component.
You can:
#1
Move LoginRegisterPage to be rendered by the component prop of the Route so it receives the route props and thus the history object as a prop.
<Route exact path="/login-register" component={LoginRegisterPage} />
LoginRegisterPage
class LoginPage extends React.Component {
constructor(props) {
...
}
...
handleClick(event) {
var apiBaseUrl = "https://myapi.com/auth/"
const payload = {...};
const { username, password } = this.state;
const { history } = this.props; // <-- destructure history from props
if (username && password) {
fetch(apiBaseUrl + 'login', payload)
.then((response) => {
...
}).then((data) => {
this.setState({
accessToken: data.accestToken,
authenticated: data.authenticated
});
localStorage.setItem('accessToken', data.accessToken);
if (data.authenticated === true) {
console.log(this.props)
this.props.history.push("/"); // <-- navigate!
}
})
.catch((err) => console.log(err));
} else {
alert("Cannot be Empty")
}
}
render() {
...
}
}
#2
Decorate your LoginRegisterPage with the withRouter Higher Order Component so the route props are injected as props.
import { withRouter } from 'react-router-dom;
...
const LoginPageWithRouter = withRouter(LoginPage);
Note
If you prefer to do a redirect then replace any history.push calls with history.replace. push is a normal navigation and pushes on a new path on the history state whereas replace replaces the current history entry in the stack. After the auth redirect you probably don't want users to back navigate back to your login page/route.
Edit
If you need the handleSuccess callback to manage some auth state in App then I think it best to let App manage the authentication state and the LoginPage to still handle navigation. In this case, go with the second solution above so it receives both the handleSuccess callback and the history object.
if (data.authenticated === true) {
this.props.onLoginSuccess(data); // <-- callback to parent to set state
this.props.history.replace("/"); // <-- imperative navigation
}
Define your handleSucess function in LoginRegisterPage instead of passing it as a prop and this should work.

Express routing trouble - POST 404 (Not Found)

Something just isn't connecting properly when I attempt to use routes specified within login.js for login.component.js.
It's strange because when I change axios.post('http://localhost:5000/login/add3', user) (/add3) to axios.post('http://localhost:5000/login/add', user) (/add) it performs the POST correctly, which leads me to believe it either isn't connected or it's connected to a different route than I specified.
Link to 404 error
Relevent Files: app.js, login.js, login.component.js, login.model.js
app.js ↓
import "bootstrap/dist/css/bootstrap.min.css";
import { BrowserRouter as Router, Route} from "react-router-dom";
import Navbar from "./components/navbar.component"
import ExercisesList from "./components/exercises-list.component";
import EditExercise from "./components/edit-exercise.component";
import CreateExercise from "./components/create-exercise.component";
import CreateUser from "./components/create-user.component";
import LoginUser from "./components/login.component";
function App() {
return (
<Router>
<div className="container">
<Navbar />
<br/>
<Route path="/" exact component={ExercisesList} />
<Route path="/edit/:id" component={EditExercise} />
<Route path="/create" component={CreateExercise} />
<Route path="/user" component={CreateUser} />
<Route path="/login" component={LoginUser} />
</div>
</Router>
);
}
export default App;
login.js ↓
let Login = require('../models/login.model');
router.route('/').get((req, res) => {
Login.find()
.then(users => res.json(users))
.catch(err => res.status(400).json('Error: ' + err));
});
router.route('/add3').post((req, res) => {
const username = req.body.username;
const password = req.body.password;
const newUser = new Login({
username,
password
});
newUser.save()
.then(() => res.json('User added!'))
.catch(err => res.status(400).json('Error: ' + err));
});
module.exports = router;
login.component.js ↓
import axios from 'axios';
export default class LoginUser extends Component {
constructor(props) {
super(props);
this.onChangeUsername = this.onChangeUsername.bind(this);
this.onChangePassword = this.onChangePassword.bind(this);
this.onSubmit = this.onSubmit.bind(this);
this.state = {
username: '',
password: ''
}
}
onChangeUsername(e) {
this.setState({
username: e.target.value
})
}
onChangePassword(e) {
this.setState({
password: e.target.value
})
}
onSubmit(e) {
e.preventDefault();
const user = {
username: this.state.username,
password: this.state.password
}
console.log(user);
axios.post('http://localhost:5000/login/add3', user)
.then(res => console.log(res.data));
}
render() {
return (
<div>
<h3>Login</h3>
<form onSubmit={this.onSubmit}>
<div className="form-group">
<input type="text"
required
className="form-control"
placeholder="Username"
value={this.state.username}
onChange={this.onChangeUsername}
/>
<input type="text"
required
className="form-control"
placeholder="Password"
value={this.state.password}
onChange={this.onChangePassword}
/>
</div>
<div className="form-group">
<input type="submit" value="Login" className="btn btn-primary" />
</div>
</form>
</div>
)
}
}
login.model.js ↓
const Schema = mongoose.Schema;
const loginSchema = new Schema({
username: {
type: String,
required: true
},
password: {
type: String,
required: true
}
});
const Login = mongoose.model('Login', loginSchema);
module.exports = Login;
Sorry if this is a common question or if there's just a super easy answer, I'm clearly new to ReactJS so I figured I'd just ask others who are far more knowledgeable on the subject
I solved this problem on accident... for future reference, just restart the connection to your database! Didn't know that could cause an issue, but here's to learning.

React Context API does not update after calling dispatch

I have a login component that stores the user information in the global state after a successful login. The login component is pretty straight forward. It contains a form with a handleSubmit event that calls an endpoint. Based on the result of that endpoint an action is taken. The login component looks like this.
import React, { Component } from 'react';
import { StateContext } from '../state';
import { login } from '../repositories/authenticationRepository';
class Login extends Component {
static contextType = StateContext;
constructor(props) {
super(props);
this.state = {
email: '',
password: '',
message: '',
};
}
handleChange = (event) => {
const { name, value } = event.target;
this.setState({ [name]: value });
}
handleSubmit = async (event) => {
event.preventDefault();
const [{}, dispatch] = this.context;
const { history } = this.props;
const { email, password } = this.state;
const isLoggedInResponse = await login({ email, password });
if (isLoggedInResponse.data.type === 'error') {
this.setState({ message: isLoggedInResponse.data.message });
return;
}
dispatch({ type: 'storeUserInformation', userInformation: isLoggedInResponse.data.message });
history.push('/');
}
render() {
const { email, password, message } = this.state;
return (
<div className="login-wrapper">
<form onSubmit={this.handleSubmit}>
<label htmlFor="email">
Email:
<input autoComplete="off" name="email" type="text" value={email} onChange={this.handleChange} />
</label>
<label htmlFor="password">
Password:
<input autoComplete="off" id="password" name="password" type="password" value={password} onChange={this.handleChange} />
</label>
{message.length > 0 && <span className="text-danger error">{message}</span> }
<input className="btn btn-secondary" type="submit" value="Submit" />
</form>
</div>
);
}
}
export default Login;
When testing it myself I can see the user information being set in the ReactJS devtools. Of course I want to test this automatically using a unit test, so I wrote the following.
jest.mock('../../repositories/authenticationRepository');
import React from 'react';
import { mount } from 'enzyme';
import Login from '../../pages/Login';
import { StateProvider } from '../../state';
import { login } from '../../repositories/authenticationRepository';
import { act } from 'react-dom/test-utils';
import history from '../../sitehistory';
import { BrowserRouter as Router } from 'react-router-dom';
import { reducer } from '../../reducer';
it('Saves the user information in the store on a succesfull login', async () => {
login.mockReturnValue(({ data: { type: 'success', message: 'Message should be stored' }}));
let initialStateMock = {}
const wrapper = mount(
<StateProvider initialState={initialStateMock} reducer={reducer}>
<Router>
<Login history={history} />
</Router>
</StateProvider>
);
let emailEvent = { target: { name: 'email', value: 'test#example.com'} }
let passwordEvent = { target: { name: 'password', value: 'password'} }
wrapper.find('input').first().simulate('change', emailEvent);
wrapper.find('input').at(1).simulate('change', passwordEvent);
const submitEvent = { preventDefault: jest.fn() }
await act(async () => {
wrapper.find('form').first().simulate('submit', submitEvent);
});
act(() => {
wrapper.update();
});
console.log(initialStateMock); // expected { userInformation: 'Message should be stored' } but got {}
});
I expect the initialStatemock to have the value of { userInformation: 'Message should be stored' }. However it still has the initial value of {}. I tried wrapper.update() to force a refresh but to no avail. What am I overlooking?

React Router will not redirect based on state

In the code, it reaches the isRegistered function, I know this as I have it console.log state. The state of registered is equal to true. So therefore based on the code it should redirect to /login but it is not.
import React from 'react'
import "./Register.css";
import {BrowserRouter as Route, Redirect, Link} from 'react-router-dom'
const initialUser = {
username: "",
email: "",
password: "",
password2: "",
name: ""
}
class Register extends React.Component {
constructor(props) {
super(props);
this.state = {
user: initialUser,
registered: ''
};
}
onUsernameChange = event => {
this.setState({ username: event.target.value });
};
onNameChange = event => {
this.setState({ name: event.target.value });
};
onEmailChange = event => {
this.setState({ email: event.target.value });
};
onPasswordChange = event => {
this.setState({ password: event.target.value });
};
onPassword2Change = event => {
this.setState({ password2: event.target.value });
};
isRegistered() {
const { registered } = this.state;
console.log(registered, 'here', this.state)
if (registered) {
return (
<Redirect to='/login' />
)
}
}
onRegister = () => {
fetch("http://localhost:3000/register", {
method: "post",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
name: this.state.name,
email: this.state.email,
username: this.state.username,
password: this.state.password,
password2: this.state.password2
})
})
.then(res => res.json())
.then(data => {
console.log(data.isRegistered);
if (data.isRegistered) {
this.setState({registered: true})
this.isRegistered();
}
})
};
render() {
return <div className="login-page">
<div className="form">
<form className="login-form">
<input type="text" placeholder="name" onChange={this.onNameChange} />
<input type="text" placeholder="username" onChange={this.onUsernameChange} />
<input type="text" placeholder="email" onChange={this.onEmailChange} />
<input type="password" placeholder="password" onChange={this.onPasswordChange} />
<input type="password" placeholder="confirm password" onChange={this.onPassword2Change} />
<button className="bluecolor" onClick={this.onRegister}>
Register
</button>
<p className="message">
Have an account? Login
</p>
</form>
</div>
</div>;
}
}
export default Register;
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
It reaches all the way to the if statement in isRegistered(). So I assume it is the redirect component that is wrong but I cannot figure it out for the life of me.
//UPDATE
This is now what I have in it
import React from 'react'
import "./Register.css";
import {BrowserRouter as Route, Redirect, withRouter} from 'react-router-dom'
const initialUser = {
username: "",
email: "",
password: "",
password2: "",
name: ""
}
class Register extends React.Component {
constructor(props) {
super(props);
this.state = {
user: initialUser,
registered: ''
};
}
onUsernameChange = event => {
this.setState({ username: event.target.value });
};
onNameChange = event => {
this.setState({ name: event.target.value });
};
onEmailChange = event => {
this.setState({ email: event.target.value });
};
onPasswordChange = event => {
this.setState({ password: event.target.value });
};
onPassword2Change = event => {
this.setState({ password2: event.target.value });
};
isRegistered() {
const { registered } = this.state;
console.log(registered, 'here', this.state)
if (registered) {
this.props.history.push('/login')
}
}
onRegister = () => {
fetch("http://localhost:3000/register", {
method: "post",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
name: this.state.name,
email: this.state.email,
username: this.state.username,
password: this.state.password,
password2: this.state.password2
})
})
.then(res => res.json())
.then(data => {
console.log(data.isRegistered);
if (data.isRegistered) {
this.setState({registered: true})
this.isRegistered();
}
})
};
render() {
return <div className="login-page">
<div className="form">
<form className="login-form">
<input type="text" placeholder="name" onChange={this.onNameChange} />
<input type="text" placeholder="username" onChange={this.onUsernameChange} />
<input type="text" placeholder="email" onChange={this.onEmailChange} />
<input type="password" placeholder="password" onChange={this.onPasswordChange} />
<input type="password" placeholder="confirm password" onChange={this.onPassword2Change} />
<button className="bluecolor" onClick={this.onRegister}>
Register
</button>
<p className="message">
Have an account? Login
</p>
</form>
</div>
</div>;
}
}
export default withRouter(Register);
And this is the main App.js
import React, { Component } from 'react';
import RegisterFull from "./Components/Register/RegisterFull";
import LoginFull from "./Components/Login/LoginFull";
import HomeFull from "./Components/Home/HomeFull";
import FullContact from "./Components/Contact/FullContact";
import './App.css';
import './Components/flex.css'
import {BrowserRouter as Router, Route} from "react-router-dom";
class App extends Component {
constructor(props) {
super(props);
this.state = {
signedIn: false
}
}
loginUser = () => {
this.setState({signedIn: true})
}
render() {
return (
<Router>
<div>
<Route exact={true} path='/' component={HomeFull}/>
<Route path='/contact' component={FullContact} />
<Route path='/login' component={LoginFull} />
<Route path='/register' component={RegisterFull} />
<Route path='/about' component={HomeFull} />
</div>
</Router>
)
}
}
export default App;
You cannot return Redirect element in render like this by invoking another method in component lifecycles or methods.
You need to wrap your component with withRouter HOC which provides history props.
import {BrowserRouter as Route,, withRouter, Redirect, Link} from 'react-router-dom'
export default withRouter(Register);
and if you want to navigate programmatically :
isRegistered = () => {
const { registered } = this.state;
console.log(registered, 'here', this.state)
if (registered) {
this.props.history.push('/login)
}
}
Some improvements in your code you could make. Here is my suggestion. you don't need to bind anything. You are using latest React. How I know? You are doing onUsernameChange = evnet => {} not onUsernameChange(event){}. Overall #Sakhi Mansoor is right.
import React from "react";
import "./Register.css";
import {
BrowserRouter as Route,
withRouter,
Redirect,
Link
} from "react-router-dom";
const initialUser = {
username: "",
email: "",
password: "",
password2: "",
name: ""
};
class Register extends React.Component {
constructor(props) {
super(props);
this.state = {
user: initialUser,
registered: ""
};
}
handleChange = event => {
this.setState({
user: {
...this.state.user,
[event.target.name]: event.target.value
}
});
};
isRegistered = () => {
const { registered } = this.state;
console.log(registered, "here", this.state);
if (registered) {
this.props.history.push("/login");
}
};
onRegister = event => {
event.preventDefault();
fetch("http://localhost:3000/register", {
method: "post",
headers: { "Content-Type": "application/json" },
body: JSON.stringify(this.state.user)
})
.then(res => res.json())
.then(data => {
console.log(data.isRegistered);
if (data.isRegistered) {
this.setState({ registered: true });
this.isRegistered();
}
});
};
render() {
return (
<div className="login-page">
<div className="form">
<form className="login-form" onSubmit={this.onRegister}>
<input
type="text"
placeholder="name"
name="name"
value={this.state.user.name}
onChange={this.handleChange}
/>
<input
type="text"
placeholder="username"
name="username"
value={this.state.user.username}
onChange={this.handleChange}
/>
<input
type="text"
placeholder="email"
name="email"
value={this.state.user.email}
onChange={this.handleChange}
/>
<input
type="password"
placeholder="password"
name="password"
value={this.state.user.password}
onChange={this.handleChange}
/>
<input
type="password"
placeholder="confirm password"
name="password2"
value={this.state.user.password2}
onChange={this.handleChange}
/>
<button className="bluecolor" type="submit">
Register
</button>
<p className="message">
Have an account? Login
</p>
</form>
</div>
</div>
);
}
}
export default withRouter(Register);
Here is a simple example of how to redirect on a button click.Hope this might help you
import React, { Component } from "react";
import { BrowserRouter,Route,Switch } from 'react-router-dom'
class App extends Component {
render() {
return (
<BrowserRouter>
<Switch>
<Route path="/" exact component={Sample}/>
<Route path="/test" exact render={()=>(<p>Test</p>)}/>
</Switch>
</BrowserRouter>
)
}
}
class Sample extends React.Component {
constructor(props) {
super(props)
this.Click = this.Click.bind(this) // you need to bind the method
}
Click() {
this.props.history.push('/test');
}
render() {
return(
<button onClick={this.Click}>Click</button>
)
}
}
export default App;

Categories

Resources