Я пытаюсь создать проверку на стороне клиента с помощью ReactJS в моей регистрационной форме. Я использую библиотеку http://validatejs.org/ для валидации вместе с https://github.com/jhudson8/react-semantic-ui компонентами для рендеринга semantic-ui. Реагировать на компоненты. Вот код.Проверка формы ReactJS, когда состояние не обновляется немедленно
var constraints = {
email: {
presence: true,
email:true
},
password: {
presence: true,
length: { minimum: 5 }
}
}
var RegistrationForm = React.createClass({
getInitialState: function() {
return {
data: {},
errors: {}
};
},
changeState: function() {
this.setState({
data: {
email: this.refs.email.getDOMNode().value,
password: this.refs.password.getDOMNode().value,
password_confirmation: this.refs.password_confirmation.getDOMNode().value
}
});
console.log("State after update");
console.log(this.state.data);
},
handleChange: function(e) {
this.changeState();
var validation_errors = validate(this.state.data, constraints);
if(validation_errors){
console.log(validation_errors);
this.setState({errors: validation_errors});
}
else
this.setState({errors: {}});
},
handleSubmit: function(e) {
e.preventDefault();
//code left out..
},
render: function() {
var Control = rsui.form.Control;
var Form = rsui.form.Form;
var Text = rsui.input.Text;
var Button = rsui.form.Button;
return (
<Form onSubmit={this.handleSubmit} onChange={this.handleChange}>
<h4 className="ui dividing header">New User Registration</h4>
<Control label="Email" error={this.state.errors.email}>
<Text name="email" type="email" ref="email" key="email" value={this.state.data.email}></Text>
</Control>
<Control label="Password" error={this.state.errors.password}>
<Text name="password" type="password" ref="password" key="password" value={this.state.data.password}></Text>
</Control>
<Control label="Password Confirmation">
<Text name="password_confirmation" type="password" ref="password_confirmation" key="password_confirmation" value={this.state.data.password_confirmation}></Text>
</Control>
<Button> Register </Button>
</Form>);
}
});
Проблема, которую я имею что когда я называю this.setState, состояние не сразу обновляется, поэтому, когда я звоню Validate (this.state.data, ограничение) Я проверку предыдущего состояния, так что пользователя Опыт пользовательского интерфейса становится странным, например:
Если у меня есть «пример @ em» в поле электронной почты, и я вхожу в «a», он будет проверять строку «example @ em 'not' example @ ema», поэтому по существу он всегда проверяет состояние перед новым нажатием клавиши. Я должен делать что-то принципиально неправильное здесь. Я знаю, что состояние компонента не обновляется сразу, только после выполнения рендеринга.
Должен ли я выполнять проверки в функции рендеринга?
--- РЕШЕНИЕ ---
Добавление обратного вызова SetState как Феликс Клинг предложил решить ее. Вот обновленный код с раствором:
var RegistrationForm = React.createClass({
getInitialState: function() {
return {
data: {},
errors: {}
};
},
changeState: function() {
this.setState({
data: {
email: this.refs.email.getDOMNode().value,
password: this.refs.password.getDOMNode().value,
password_confirmation: this.refs.password_confirmation.getDOMNode().value
}
},this.validate);
},
validate: function() {
console.log(this.state.data);
var validation_errors = validate(this.state.data, constraints);
if(validation_errors){
console.log(validation_errors);
this.setState({errors: validation_errors});
}
else
this.setState({errors: {}});
},
handleChange: function(e) {
console.log('handle change fired');
this.changeState();
},
handleSubmit: function(e) {
e.preventDefault();
console.log(this.state);
},
render: function() {
var Control = rsui.form.Control;
var Form = rsui.form.Form;
var Text = rsui.input.Text;
var Button = rsui.form.Button;
return (
<Form onSubmit={this.handleSubmit} onChange={this.handleChange}>
<h4 className="ui dividing header">New Rowing Club Registration</h4>
<Control label="Email" error={this.state.errors.email}>
<Text name="email" type="email" ref="email" key="email" value={this.state.data.email}></Text>
</Control>
<Control label="Password" error={this.state.errors.password}>
<Text name="password" type="password" ref="password" key="password" value={this.state.data.password}></Text>
</Control>
<Control label="Password Confirmation">
<Text name="password_confirmation" type="password" ref="password_confirmation" key="password_confirmation" value={this.state.data.password_confirmation}></Text>
</Control>
<Button> Register </Button>
</Form>);
}
});
--- лучшее решение ----- решение
знакомства FakeRainBrigand в ниже.
Спасибо! Это решение имеет намного меньший рендеринг. Я не знал о дополнениях React. Одна вещь, которую я должен был сделать, это добавить функцию .bind (this) в getValue, так что вызов this.refs будет иметь правильный контекст. – blushrt
Для тех, кто использует камень с ребрами, обязательно добавьте config.react.addons = true в application.rb, чтобы вы могли получить доступ к React.addons – blushrt
Но я не согласен с тем, что ошибки формы представляют собой кеш данных данных здесь, они должно быть частью государства. – blushrt