Вы должны хранить данные формы в состоянии вашего компонента.Например, this.state.email
вместо this.email
.Когда данные, хранящиеся в состоянии компонента, обновляются, запускается повторное рендеринг.Однако повторные визуализации не инициируются для обновлений переменных простого класса.Вы также напрямую управляете состоянием, когда устанавливаете errors
.Вместо этого вам следует использовать метод setState
docs .
. Причина, по которой вы не видите свою ошибку, отображаемую на странице, заключается в том, что ваша страница неправильно перерисовывается из-за изменений в форме.
Обратите внимание, что это также хорошая идея, чтобы обернуть переменные данных формы в объект formData
в пределах состояния для организации.Это помогает отделить данные формы от остального состояния компонента (например, сохранить значения формы отдельно от переменной ошибок) и позволяет легче передавать данные формы, например, во время отправки формы.
Здесьпример того, как вы можете реорганизовать вещи:
constructor(props){
super(props);
this.state = {
formData: { // set up default form values
email: "",
password: "",
},
errors: {},
}
handleChange = event => {
const { formData } = this.state;
this.setState({
formData: {
...formData, // leave other values unchanged
[event.target.name]: event.target.value, // update the changed value
}
});
}
handleSubmit(event) {
event.preventDefault();
const { formData, errors } = this.state;
const { email, password } = formData;
if (password.length < 6) { // changed comparison to _less_ than
this.setState({ // update errors using setState -- never directly modify a component's state
errors: {
...errors,
password: "Password must be at least 6 characters",
}
});
}
const creds = {email, password}
if (creds.email && creds.password) { // objects are never falsey, so we need to check each field directly
this.props.signUp(creds);
this.props.history.push('/');
}
}
render() {
return (
<div className="container">
<div className="row">
<div className="col-md-6">
<h1>Sign Up</h1>
<form onSubmit={this.handleSubmit}>
<div className="form-group">
<label htmlFor="exampleInputEmail1">Email address</label>
<input
name="email"
type="email"
className="form-control"
id="email"
value={ this.state.formData.email } {/* control component by storing value in state and updating state when the input changes */}
onChange={ this.handleChange }
aria-describedby="emailHelp"
placeholder="Enter email" />
<small id="emailHelp" className="form-text text-muted">We'll never share your email with anyone else.</small>
</div>
<div className="form-group">
<label htmlFor="exampleInputPassword1">Password</label>
{this.state.errors.password &&
//display an error here
<h2>{this.state.errors.password}</h2>
}
<input
name="password"
type="password"
value={ this.state.formData.password }
onChange={ this.handleChange }
className="form-control"
id="password"
placeholder="Password" />
</div>
<button type="submit" className="btn btn-primary">Submit</button>
</form>
</div>
</div>
</div>
);
}
}
Примечание. Если в вашей форме есть поля с флажками, показанный метод handleChange
не будет работать должным образом для этих полей, поскольку свойство checked
объектавместо свойства value
следует использовать флажок.Для простоты я включил только случай без флажка, но вот полная версия handleChange
:
handleChange = event => {
const { formData } = this.state;
const { name, type, value, checked } = event.target;
this.setState({
formData: {
...formData,
[name]: type === "checkbox" ? checked : value,
}
})
}