Gre*_*egg 17 validation reactjs redux redux-form
我正在使用redux-form模糊验证.在我将第一个字符输入到输入元素后,它会失去焦点,我必须再次单击它才能继续输入.它只对第一个字符执行此操作.后续字符类型仍然是焦点.这是我的基本签到形式示例:
import React, { Component } from 'react';
import { connect } from 'react-redux';
import { Field, reduxForm } from 'redux-form';
import * as actions from '../actions/authActions';
require('../../styles/signin.scss');
class SignIn extends Component {
handleFormSubmit({ email, password }) {
this.props.signinUser({ email, password }, this.props.location);
}
renderAlert() {
if (this.props.errorMessage) {
return (
<div className="alert alert-danger">
{this.props.errorMessage}
</div>
);
} else if (this.props.location.query.error) {
return (
<div className="alert alert-danger">
Authorization required!
</div>
);
}
}
render() {
const { message, handleSubmit, prestine, reset, submitting } = this.props;
const renderField = ({ input, label, type, meta: { touched, invalid, error } }) => (
<div class={`form-group ${touched && invalid ? 'has-error' : ''}`}>
<label for={label} className="sr-only">{label}</label>
<input {...input} placeholder={label} type={type} className="form-control" />
<div class="text-danger">
{touched ? error: ''}
</div>
</div>
);
return (
<div className="row">
<div className="col-md-4 col-md-offset-4">
<form onSubmit={handleSubmit(this.handleFormSubmit.bind(this))} className="form-signin">
<h2 className="form-signin-heading">
Please sign in
</h2>
{this.renderAlert()}
<Field name="email" type="text" component={renderField} label="Email Address" />
<Field name="password" type="password" component={renderField} label="Password" />
<button action="submit" className="btn btn-lg btn-primary btn-block">Sign In</button>
</form>
</div>
</div>
);
}
}
function validate(values) {
const errors = {};
if (!values.email) {
errors.email = 'Enter a username';
}
if (!values.password) {
errors.password = 'Enter a password'
}
return errors;
}
function mapStateToProps(state) {
return { errorMessage: state.auth.error }
}
SignIn = reduxForm({
form: 'signin',
validate: validate
})(SignIn);
export default connect(mapStateToProps, actions)(SignIn);
Run Code Online (Sandbox Code Playgroud)
ris*_*ott 30
发生这种情况是因为您renderField每次渲染时都将其重新定义为新组件,这意味着它看起来像是React 的新组件,因此它将卸载原始组件并重新安装新组件.
你需要提升它:
const renderField = ({ input, label, type, meta: { touched, invalid, error } }) => (
<div class={`form-group ${touched && invalid ? 'has-error' : ''}`}>
<label for={label} className="sr-only">{label}</label>
<input {...input} placeholder={label} type={type} className="form-control" />
<div class="text-danger">
{touched ? error: ''}
</div>
</div>
);
class SignIn extends Component {
...
render() {
const { message, handleSubmit, prestine, reset, submitting } = this.props;
return (
<div className="row">
<div className="col-md-4 col-md-offset-4">
<form onSubmit={handleSubmit(this.handleFormSubmit.bind(this))} className="form-signin">
<h2 className="form-signin-heading">
Please sign in
</h2>
{this.renderAlert()}
<Field name="email" type="text" component={renderField} label="Email Address" />
<Field name="password" type="password" component={renderField} label="Password" />
<button action="submit" className="btn btn-lg btn-primary btn-block">Sign In</button>
</form>
</div>
</div>
);
}
}
...
Run Code Online (Sandbox Code Playgroud)
正如@riscarrott 提到的,放在renderField组件类之外。
但我仍然失去焦点.. 经过测试,我得出结论,由于使用了柯里化函数(返回另一个函数,而不是直接返回元素。),重新渲染完成。
const const renderField = (InputComponent = 'input') => ({ input, label, type, meta: { touched, invalid, error } }) => (
<div class={`form-group ${touched && invalid ? 'has-error' : ''}`}>
<label for={label} className="sr-only">{label}</label>
<InputComponent {...input} placeholder={label} type={type} className="form-control" />
<div class="text-danger">
{touched ? error: ''}
</div>
</div>
);
Run Code Online (Sandbox Code Playgroud)
然后,如果您renderField是咖喱函数:
//.....
<Field name="email" type="text" component={renderField('input')} label="Email Address" />
<Field name="desc" component={renderField('textarea')} label="Email Address" />
Run Code Online (Sandbox Code Playgroud)
// outside component class
const InputField = renderField('input');
const TextAreaField = renderField('textarea');
// inside component class
<Field name="email" type="text" component={InputField} label="Email Address" />
<Field name="desc" component={TextAreaField} label="Email Address" />
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
4238 次 |
| 最近记录: |