我正在制作一份有关反应的登记表。我对它的验证部分有点困惑。
截至目前,我在控制台上收到以下警告四次:“警告不要直接改变状态。使用setState()react / no-direct-mutation-state。”
我猜我得到这些错误的原因是因为这些语句“this.state.errors.firstName =”名字必须至少为2个字符。“;”并喜欢这个“this.state.errors = {};”在我的代码中。
但是,我不知道如何做得更好并消除警告。如果你能为我提供一个更好的方法,那将是非常棒的。任何帮助将受到高度赞赏。非常感谢提前!
import React, { Component } from 'react';
import {withRouter} from "react-router-dom";
import HeaderPage from './HeaderPage';
import Logo from './Logo';
import RegistrationForm from './RegistrationForm';
import axios from 'axios';
class Registration extends Component {
mixins: [
Router.Navigation
];
constructor(props) {
super(props);
this.state = {
firstName:'',
lastName:'',
email:'',
errors:{},
helpText: '',
helpUrl: '',
nextLink:''
};
this.setUserState = this.setUserState.bind(this);
this.registrationFormIsValid = this.registrationFormIsValid.bind(this);
this.saveUser = this.saveUser.bind(this);
}
setUserState(e){
const target = e.target;
const value = target.value;
const name = target.name;
this.setState({[name]: value});
//delete this line
console.log(this.state[name]);
}
registrationFormIsValid(){
var formIsValid = true;
this.state.errors = {};
//validate first name
if(this.state.firstName.length < 2){
this.state.errors.firstName = "First name must be at least 2 characters.";
formIsValid = false;
}
//validate last name
if(this.state.lastName.length < 2){
this.state.errors.lastName = "Last name must be at least 2 characters.";
formIsValid = false;
}
//validate email
if(this.state.email.length < 2){
this.state.errors.email = "Email must be at least 2 characters.";
formIsValid = false;
}
this.setState({errors : this.state.errors});
return formIsValid;
}
saveUser(e, { history }){
e.preventDefault();
// const errorWrappers = document.getElementsByClassName('input');
// for (var i=0; i < errorWrappers.length; i++) {
// const isError= errorWrappers[i].innerHTML;
// if (isError.length > 0){
// errorWrappers[i].previousSibling.className = "error-input"
// }
// }
if(!this.registrationFormIsValid()){
return;
}
const values = {
firstName: this.state.firstName,
lastName: this.state.lastName,
email: this.state.email,
password: this.state.password,
phone: this.state.phone,
address: this.state.address,
dob: this.state.birthday
}
if (this.props.userRole === 'instructor'){
axios.post(`/instructors`, values)
.then((response)=> {
//delete this line
console.log(response);
})
.catch((error) => {
console.log(error + 'something went wrooooong');
});
this.props.history.push("/success-instructor");
}else{
axios.post(`/students`, values)
.then((response)=> {
//delete this line
console.log(response);
})
.catch((error) => {
console.log(error + 'something went wrooooong');
});
if (this.props.parent === "false"){
this.props.history.push("/success-student");
}else{
this.props.history.push("/success-parent");
}
}
}
//end of validation
render() {
return (
<div className="Registration">
<div className="container menu buttons">
<HeaderPage/>
</div>
<div className="page container narrow">
<div className="cover-content">
<Logo/>
<div className="container">
<h2 className="page-title">{this.props.title}</h2>
<a className="helpLink" href={this.props.helpUrl}>{this.props.helpText}</a>
<div className="main-content background-white">
<RegistrationForm
userRole={this.props.userRole}
onChange={this.setUserState}
onSave={this.saveUser}
errors={this.state.errors}
/>
<br/>
<br/>
<br/>
</div>
</div>
</div>
</div>
</div>
);
}
}
export default withRouter(Registration);
答案 0 :(得分:1)
而不是
this.state.errors = {};
和
this.state.errors.lastName = "Last name must be at least 2 characters.";
使用
this.setState({errors = {}});
this.setState({ errors: { lastName: "Last name must be at least 2 characters." } });
你需要避免直接改变状态。
警告本身回答了这个问题。请阅读React Doc 小心。
“警告不要直接改变状态。使用setState() 反应/无直接突变状态“。
答案 1 :(得分:1)
不要改变state
不要有直接改变状态的代码。相反,创建新对象并进行更改。使用setState
完成更改更新状态后。
而不是:
this.state.errors.someError1="e1";
this.state.errors.someError2="e2";
这样做:
this.errorsObject=Object.assign({},this.state.errors,{someError1:"e1",someError2:"e2"};
最后:
this.setState({
errors:this.errorsObject
});
Object.assign允许我们将一个对象的属性合并到另一个对象的属性中,用匹配的名称替换属性的值。我们可以使用它来复制对象的值而不改变现有的值。