表单验证后如何将用户发送到下一页?

Posted

技术标签:

【中文标题】表单验证后如何将用户发送到下一页?【英文标题】:How to send User to Next Page After form validation in react? 【发布时间】:2020-10-25 11:34:18 【问题描述】:

这在我的注册组件中,如果用户名和密码正确,我会尝试将用户发送到登录组件。

这是下面的注册码,

import React,  Component  from 'react';
import  Link  from 'react-router-dom';
import Axios from 'axios';

const initianValue = 
  username: '',
  password: '',
  nameError: '',
  passError: '',
  dataError: '',
;

class SignUp extends Component 
  constructor(props) 
    super(props);
    this.state = initianValue;
    this.handleInputChange = this.handleInputChange.bind(this);
    this.handleSubmit = this.handleSubmit.bind(this);
  

  handleInputChange = (e) => 
    this.setState(
      [e.target.name]: e.target.value,
    );
  ;

  validForm() 
    let nameError = '';
    let passError = '';
    let dataError = '';

    const user = 
      username: this.state.username,
      password: this.state.password,
    ;

    if (!this.state.username) 
      nameError = 'Enter Name';
    

    if (user.username !== '' && user.password !== '') 
      Axios.post('http://localhost:9000/checkUser', user)
        .then((res) => this.setState( dataError: res.data ))
        .catch((err) => console.log(err));
    

    if (!this.state.password) 
      passError = 'Enter Password';
    

    if (nameError || passError || dataError) 
      this.setState(
        nameError,
        passError,
        dataError,
      );
      return false;
    

    return true;
  

  handleSubmit = (e) => 
    e.preventDefault();
    const isvalid = this.validForm();
    if (isvalid) 
      this.setState(initianValue, () => this.props.history.push('/SignIn'));
    
  ;

  render() 
    return (
      <div className='Main'>
        <span className='create'>Create Account</span>
        <div className='SignUp'>
          <form onSubmit=this.handleSubmit>
            <div className='form-group'>
              <label>Username</label>
              <input
                type='text'
                name='username'
                value=this.state.username
                className='form-control'
                onChange=this.handleInputChange
              />
              <div className='error'>
                this.state.nameError
                this.state.dataError
              </div>
              <br />
              <label>Password</label>
              <input
                type='password'
                name='password'
                value=this.state.password
                className='form-control'
                onChange=this.handleInputChange
              />
              <div className='error'>this.state.passError</div>
              <br />

              <button type='submit' className='btn btn-primary'>
                Sign Up
              </button>
            </div>
          </form>
        </div>
        <div className='signinForm'>
          <label>
            Already Have Account <Link to='/Signin'> Sign In </Link>
          </label>
        </div>
      </div>
    );
  


export default SignUp;

如果我输入正确的用户名和密码但输入错误的用户名/密码,它的工作完美,它也会将我发送到登录页面并在控制台中显示这样的警告

index.js:1 Warning: Can't perform a React state update on an unmounted component. This is a no-op, but it indicates a memory leak in your application. To fix, cancel all subscriptions and asynchronous tasks in the componentWillUnmount method.
    in SignUp (created by Context.Consumer)

我包装了组件注册和登录路由器,

如果用户名和密码在数据库中正确,这是我的 server.js 文件发送数据

app.post('/checkUser', function (req, res) 
  const name = req.body.username;
  const pass = req.body.password;

  conn.query(
    `SELECT * FROM users WHERE username  = (?) AND password = (?) `,
    [name, pass],
    (err, rows) => 
      if (err) throw err;

      if (!rows.length) 
        res.send('Wrong Data');
      
    
  );
);

【问题讨论】:

【参考方案1】:

您的validForm 进行异步调用。当异步调用完成时,validForm 函数和handleSubmit 函数的执行已经完成。然后 then 块在您设置状态的地方执行,因此会出现错误。

解决方案:将validForm 设为异步函数并等待您的异步调用。还将handleSubmit 函数设为异步并等待validForm

Working demo

代码 sn-p

class SignUp extends Component 
  constructor(props) 
    super(props);
    this.state = initianValue;
    this.handleInputChange = this.handleInputChange.bind(this);
    this.handleSubmit = this.handleSubmit.bind(this);
  

  handleInputChange = e => 
    this.setState(
      [e.target.name]: e.target.value
    );
  ;

  async validForm() 
    let nameError = "";
    let passError = "";
    let dataError = "";

    const user = 
      username: this.state.username,
      password: this.state.password
    ;

    if (!this.state.username) 
      nameError = "Enter Name";
    

    if (user.username !== "" && user.password !== "") 
      await Axios.get("https://jsonplaceholder.typicode.com/todos/1", user) //fake api
        .then(res => 
          dataError = "user already exists"; //provide dynamic error..
          //this.setState( dataError: res.data ); // not required
        )
        .catch(err => console.log("err", err));
    

    if (!this.state.password) 
      passError = "Enter Password";
    

    if (nameError || passError || dataError) 
      this.setState(
        nameError,
        passError,
        dataError
      );
      return false;
    

    return true;
  

  handleSubmit = async e => 
    e.preventDefault();
    const isvalid = await this.validForm();
    if (isvalid) 
      this.setState(initianValue, () => this.props.history.push("/SignIn"));
    
  ;

  render() 
    return (
      <div className="Main">
        <span className="create">Create Account</span>
        <div className="SignUp">
          <form onSubmit=this.handleSubmit>
            <div className="form-group">
              <label>Username</label>
              <input
                type="text"
                name="username"
                value=this.state.username
                className="form-control"
                onChange=this.handleInputChange
              />
              <div className="error">
                this.state.nameError
                this.state.dataError
              </div>
              <br />
              <label>Password</label>
              <input
                type="password"
                name="password"
                value=this.state.password
                className="form-control"
                onChange=this.handleInputChange
              />
              <div className="error">this.state.passError</div>
              <br />

              <button type="submit" className="btn btn-primary">
                Sign Up
              </button>
            </div>
          </form>
        </div>
        <div className="signinForm">
          <label>
            Already Have Account <Link to="/Signin"> Sign In </Link>
          </label>
        </div>
      </div>
    );
  

【讨论】:

【参考方案2】:

问题可能在于处理获取的响应。这只是一个快速的猜测,但尽量不要设置 dataError 的状态,而只是修改您在此本地函数中声明的变量 dataError 的值,而不是类变量。那有意义吗?当您签入“if (nameError || passError || dataError)”时,您正在检查函数的局部变量,而不是我认为可以的类,但如果响应是错误的,您不会更改变量. 其次,如果您更改 setState 然后检查 state.dataError 您可能还没有在函数中获得更新的值刷新。

让我知道这是否有意义以及是否有效。

【讨论】:

没有得到它!我是说怎么做?

以上是关于表单验证后如何将用户发送到下一页?的主要内容,如果未能解决你的问题,请参考以下文章

PHP验证链接到下一页

在进入下一页之前使用数据库验证表单

vee-validate 按钮验证

提交表单时将语言参数传递到下一页(url)

将数据从按钮传输到下一页的帖子表单。 Django的

登录页面上的 jQuery Mobile 表单验证