【问题标题】:ReactJS - input validation doesn't validateReactJS - 输入验证不验证
【发布时间】:2018-08-30 09:17:26
【问题描述】:

我正在尝试对我的表单进行验证。

class Car extends Component {
    constructor() {
        super();
        this.state = {
            name: '',
            errors: {}
        }
     this.handleNameChange = this.handleNameChange.bind(this);
     this.handleSubmit = this.handleSubmit.bind(this);
    }

    componentWillReceiveProps(nextProps) {
        if(nextProps.errors) {
            this.setState({
                errors: nextProps.errors
            });
        }
    }

    handleNameChange(e) {
        this.setState({
            [e.target.name]: e.target.value
        })
    }

    handleSubmit(e) {
        e.preventDefault();
        const car = {
            name: this.state.name,
            ...
        }
        console.log(car);

        axios.post('/api/cars/create', car)
            .then(response => {
                console.log('response.data: ', response.data);

            }).catch(function(err) {
                console.log(err)
            });

    }

    render() {
        const { errors } = this.state;
        console.log('errors name: ', errors.name);
        ...
        return (
            <div className="container" style={{ marginTop: '50px'}}>
                <h2 style={{marginBottom: '40px'}}>Cars</h2>
                <form className="" onSubmit={ this.handleSubmit }>
                    <div className="row">
                        <div className="col-sm-3">
                            <div className="form-group"> 
                                <label>Car Name</label>
                                <input
                                    type="text"
                                    placeholder="Name"
                                    className={classnames('form-control form-control-sm', {
                                        'is-invalid': errors.name
                                    })}
                                    name="name"
                                    onChange={ this.handleNameChange }
                                    value={ this.state.name }
                                />
                                {errors.name && (<div className="invalid-feedback">{errors.name}</div>)}
                            </div>
                        </div>
                        ...
                       );
    }
}
Car = {
    //registerUser: PropTypes.func.isRequired,
    auth: PropTypes.object.isRequired,
    errors: PropTypes.object.isRequired
};

const mapStateToProps = state => ({
    auth: state.auth,
    errors: state.errors
});

export default connect(mapStateToProps,{ registerUser })(withRouter(Car))

然后,在 car.js 中,我有以下内容:

const express = require('express');
const router = express.Router();
const bcrypt = require('bcryptjs');
const jwt = require('jsonwebtoken');
const passport = require('passport');
const validateCarInput = require('../validation/car');

const Car = require('../models/Car');

router.post('/create', function(req, res) {
    console.log('in /create');
    console.log('req.body.name: '+req.body.name);

    const { errors, isValid } = validateCarInput(req.body);

    if(!isValid) {
        console.log('hello from validation');
        return res.status(400).json(errors);
    }
    ...

如果我发送的表单包含不正确的字段(空 name),我将在此处收到来自控制台 hello from validation 的消息。这里很好。

这里还有 validations/car.js 文件:

const Validator = require('validator');
const isEmpty = require('./is-empty');

module.exports = function validateCarInput(data) {
    let errors = {};
    console.log('x data.name: ', data.name);
    data.name = !isEmpty(data.name) ? data.name : '';

    if(Validator.isEmpty(data.name)) {
        errors.name = 'Name field is required';
        console.log('errors.name: ', errors.name);    
    }

    return {
        errors,
        isValid: isEmpty(errors)
    }
}

有什么问题 - 当我发送带有空 name 字段的表单时 - 这意味着该字段无效 - 它不能为空 - NodeJS 能够识别这一点,但对于 ReactJS 组件来说不是这个信息通过了。

在组件中,console.log('errors name: ', errors.name); 这行代码总是为errors.name 产生 undefined - 然后,此信息永远不会显示在网站上:

{errors.name && (<div className="invalid-feedback">{errors.name}</div>)}

为什么 ReactJS 看不到来自 NodeJS 的消息,而 errors.name 总是 undefined

【问题讨论】:

  • 当你的服务器端验证失败时,这个console.log会被执行吗? .catch(function(err) { console.log(err) })
  • 嗨@Dacreenny,是的 - 这是输出:Error: Request failed with status code 400
  • @user2932090 你的服务器响应是什么样的?
  • @xdhe 服务器响应是 { name: 'Name field is required' } - 看起来我无法将此对象从服务器添加到 setState。当我尝试this.setState({ errors: err.response.data }) 时,我得到Unhandled Rejection (TypeError): Cannot read property 'setState' of undefined
  • @user2932090 嗯我不太熟悉反应,因为我更喜欢离子。但是以我的经验,如果服务器发送 400,我的服务器响应是在响应的属性错误中很深。因此,在您的情况下,您的服务器可能会在respond.error.name 中响应。确定你能console.log那个吗?

标签: javascript node.js reactjs validation


【解决方案1】:

根据 axio 文档,错误响应由可选的 response 对象构成。响应对象(如果存在)应包含您的服务器端 json 验证数据,这是您想要更新组件状态的内容:

这可能就像进行以下更改一样简单:

axios.post('/api/cars/create', car)
.then(response => {
  console.log('response.data: ', response.data);

})
.catch((error) => { // Use arrow function to simplify setState access 

  // If error contains response data, attempt to extract server
  // side validation to update component state
  if(error.response) {
    this.setState({ errors : error.response.data })
  }
  else {
    console.log(error)
  }
})

有关 axio 错误处理的更多信息,请参阅https://github.com/axios/axios#handling-errors

【讨论】:

  • 谢谢@DacreDenny,这似乎是正确的方法。但是,当我尝试像这样更新setState 时,我得到Unhandled Rejection (TypeError): Cannot read property 'setState' of undefined。将对象分配给状态对象似乎存在问题。
  • 您好,不客气 - 您是否将 catch 函数更改为箭头函数?像这样? .catch((error) =&gt; {
  • 哦,哇,我没有!我忽略了它!谢谢,它现在可以工作了;)我是 ReactJS/NodeJS 的新手,所以我没有完全理解箭头函数等的概念,所以这也有点令人困惑。
  • 很高兴听到它现在正在工作 - 是的,箭头函数略有不同,它们有一些有趣的属性,但在这样的情况下非常有用:-)
【解决方案2】:

我认为您应该在请求中输入 .catch((error) =&gt; this.setState({error: {names: error}})) 但我认为名称应该是这样的 .catch(function(error) =&gt; this.setState({errors: {[name]: error}})) 但您必须知道有错误的字段的名称是什么

【讨论】:

  • 认为在你提到的那一行,err 中只有这条消息:Error: Request failed with status code 400 - 一些通用的(不确定它来自哪里)。但是,如果我从验证器中打印出错误消息,我会得到:{ name: 'Name field is required' }——并且这条消息不知何故没有传递给 React。
猜你喜欢
  • 1970-01-01
  • 2017-05-08
  • 1970-01-01
  • 2015-09-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-12-04
相关资源
最近更新 更多