对于redux来说还是新手。
我试图验证的是,两个关键字段不能保持相同的值,并且所有字段都是必需的。对于所需的部分,我正在使用字段级验证,似乎工作正常。为了确定元素是否已经存在,我正在使用同步验证。
同步验证工作时,我用控制台日志检查了它。它捕获错误并将其添加到errors对象。但是我的表格没有表明......是不是没有绑定?我在这里缺少什么?
我添加了&#39; onFocus&#39;和&#39; onBlur&#39;鼠标事件到文本字段,然后只读取onBlur。他们似乎工作得很好。但是在我添加的那一刻,我的{touched && error && <span>{error}</span>}
错误停止显示。我在这做错了什么?
我的表格
const required = value => (value ? "" : "required")
class CreateObject extends React.Component {
enableTextField = (e) => {
document.getElementById(e.target.id).removeAttribute("readonly");
}
disableTextField = (e) => {
document.getElementById(e.target.id).setAttribute("readonly", true);
}
renderField = ({ input, label, type, id, meta: { touched, error } }) => (
<React.Fragment>
{touched && error && <span>{error}</span>}
<FormControl {...input} type={type} placeholder={label} id={id}
className={`align-inline object-field-length ${error ? 'error' : ''}`}
onFocus={this.enableTextField.bind(this)}
onBlur={this.disableTextField.bind(this)}
/>
</React.Fragment>
);
renderObjects = ({ fields, meta: { touched, error, submitFailed, errors } }) => {
return (
<ul>
<li>
<center>
<Button bsStyle="success" onClick={() => fields.push({})}>Add New Object</Button>
</center>
</li>
{fields.map((object, index) => (
<li key={index}>
<br />
<center>
<Field
name={`${object}.key`}
type='text'
component={this.renderField}
validate={required}
label="Key"
id={`${object}.key`}
/>
<div className="divider" />
<Field
name={`${object}.method`}
type='text'
component={this.renderField}
label="Method"
validate={required}
id={`${object}.key` + `${object}.method`}
/>
<div className="divider" />
<Field
name={`${object}.value`}
type='text'
component={this.renderField}
label="Value"
validate={required}
id={`${object}.key` + `${object}.value`}
/>
<div className="divider" />
<span
className="align-inline"
onClick={() => fields.remove(index)}
className="allIcons mdi mdi-delete-forever"
/>
</center>
</li>
)
)}
</ul>
);
}
submit() {
//this
}
render() {
const { handleSubmit, pristine, reset, submitting, invalid } = this.props;
console.log(this.props);
return (
<form onSubmit={handleSubmit(this.submit.bind(this))}>
<FieldArray name='objects' component={this.renderObjects} />
<center>
<Button className="align-inline" type="submit" disabled={pristine || submitting || invalid}>Submit</Button>
<div className="divider" />
<Button className="align-inline" disabled={pristine || submitting} onClick={reset}> Clear All Values </Button>
</center>
</form>
);
}
}
export default reduxForm({
form: 'ObjectRepo',
validate
})(CreateObject);
validate.js
const validate = values => {
const error = {}
if (!values.objects || !values.objects.length) {
error.objects = { _error: 'At least one object must be entered' }
} else {
const objectArrayErrors = []
values.objects.forEach((object, objectIndex) => {
const objectErrors = { _error: 'Object Key should be unique' }
if (values.objects.filter(item => item.key == object.key).length == 2) {
objectArrayErrors[objectIndex] = objectErrors
}
})
if (objectArrayErrors.length) {
error.objects = objectArrayErrors
}
}
console.log(error)
return error
}
export default validate
提前多多感谢!
答案 0 :(得分:1)
您可能需要查看下面适合我的代码。这是您的容器(如果您愿意,还可以是智能组件)
export const validateProps = {
name: [required],
value: [required, intOrFloat, maxPercent],
someId: [required],
}
export const transformer = new TypesModel({
name: String,
value: Number,
someId: Number,
})
export default createFormContainer(
formName,
'your_form',
transformer,
validateProps,
mapStateToProps,
mapDispatchToProps,
null,
false,
null,
onSuccessSubmit)(YourFormContainer)
类型模型的代码是
class TypesModel {
constructor(schema) {
this.schema = schema
}
transform(data) {
const keys = Object.keys(this.schema)
const result = {}
for (let index = 0, len = keys.length; index < len; index += 1) {
const keyName = keys[index]
try {
result[keyName] = this.schema[keyName](data[keyName])
} catch (e) {
throw new Error(`Type conversion for field "${keyName}" failed`)
}
}
return result
}
}
export default TypesModel
您希望验证器看起来像:
export const required = value => isEmpty(value) &&
'Required field'
export const intOrFloat = value => (!isInt(`${value}`) && !isFloat(`${value}`)) &&
'Must be an integer of float'