user10039647
user10039647

Reputation:

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? <a href="/login">Login</a>
              </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? <a href="/login">Login</a>
              </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;

Upvotes: 1

Views: 65

Answers (3)

Ziyo
Ziyo

Reputation: 604

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? <a href="/login">Login</a>
            </p>
          </form>
        </div>
      </div>
    );
  }
}

export default withRouter(Register);

Upvotes: 0

Harikrishnan
Harikrishnan

Reputation: 1097

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;

Upvotes: 0

Sakhi Mansoor
Sakhi Mansoor

Reputation: 8102

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)
 }
}

Upvotes: 2

Related Questions