React Dropzone + Redux 表单验证不起作用
React Dropzone + Redux form validation doesn't work
我正在使用 React Dropzone 将文件输入添加到 Redux 表单。调用验证函数并返回正确的错误,但 error
和 tocuhed
的值没有改变:
字段渲染方法:
export const renderDropzoneField = function({ input, name, id, meta: { touched, error } }) {
return (
<div>
<Dropzone
name={name}
onDrop={filesToUpload => input.onChange(filesToUpload)}
>
Import image to upload
{touched && error && <span>{error}</span>}
</Dropzone>
</div>
);
}
验证方法:
export const validateImage = imageList => {
if (imageList) {
if (imageList.length > 1) {
return "You can upload one image at a time";
} else if (imageList.length === 1) {
let selectedImage = imageList[0];
if (!selectedImage.type.match('image.*')) {
return "Only image files are allowed";
} else if (selectedImage.size > 1048576) {
return "Maximum file size exceeded";
}
}
}
};
渲染方法:
render() {
const { handleSubmit } = this.props;
return (
<div>
<form onSubmit={handleSubmit(this._onSubmit.bind(this))}>
<Field name="title" label="Name" type="text" component={renderInputField}/>
<Field name="description" label="Description" type="text" component={renderTextAreaField}/>
<Field name="amount" label="Amount" type="text" component={renderInputField}/>
<Field name="image" component={renderDropzoneField}/>
<button type="submit" className="btn btn-primary">Create</button>
<button type="button" className="btn btn-primary" onClick={this.props.onClose}>Cancel</button>
</form>
{ this.state.error ? <span>{this.state.error}</span> : <noscript/> }
</div>
);
}
当我加载 'pdf' 文件(导致出现错误消息)时,touched
值仍然为 false,error
为 undefiend
。
更新 1
验证在表单级别完成:
const validators = [
{
field: 'title',
validator: validateName
},
{
field: 'description',
validator: validateDescription
},
{
field: 'amount',
validator: validateAmount
},
{
field: 'image',
validator: validateImage
}
];
class NewExpense extends Component {
constructor(props) {
super(props);
this.state = {
error: undefined
};
}
_onSubmit = values => {
let reader = new FileReader();
reader.onloadend = e => {
var imageValue = reader.result;
this.props.createExpense(values, imageValue, this.props.groupId, () => this.props.onClose(), error => this.setState({error: error}));
};
reader.readAsDataURL(values.image[0]);
}
_onImagePreviewChange = files => {
debugger;
}
render() {
const { handleSubmit } = this.props;
return (
<div>
<form onSubmit={ handleSubmit(this._onSubmit.bind(this)) }>
<Field name="title" label="Name" type="text" component={ renderInputField }/>
<Field name="description" label="Description" type="text" component={ renderTextAreaField }/>
<Field name="amount" label="Amount" type="text" component={ renderInputField }/>
<Field onChange={this._onImagePreviewChange.bind(this)} name="image" label="Image" component={ renderDropzoneField } />
<button type="submit" className="btn btn-primary">Create</button>
<button type="button" className="btn btn-primary" onClick={this.props.onClose}>Cancel</button>
</form>
{ this.state.error ? <span>{this.state.error}</span> : <noscript/> }
</div>
);
}
}
export default connect(null, { createExpense })(reduxForm({
validate,
form:'NewExpense',
validators
})(NewExpense));
您是否在提交表单时阻止默认操作的发生?如果不是,页面将刷新并清除触摸和错误状态。
在 handleSubmit(event)
中,您应该包括以下行:
event.preventDefault();
这将防止在单击“提交”时刷新页面。
从您的代码中不清楚您是如何触发验证的(是提交级别还是字段级别?)。不管怎样,我组装了一个沙箱,它可以工作 here。
我所做的是将验证 属性 添加到您的字段
<Field validate={validateImage} name="image" component={renderDropzoneField} />
并使用 dirty
而不是 touch
{dirty &&(error && <span>{error}</span>)}
我正在使用 React Dropzone 将文件输入添加到 Redux 表单。调用验证函数并返回正确的错误,但 error
和 tocuhed
的值没有改变:
字段渲染方法:
export const renderDropzoneField = function({ input, name, id, meta: { touched, error } }) {
return (
<div>
<Dropzone
name={name}
onDrop={filesToUpload => input.onChange(filesToUpload)}
>
Import image to upload
{touched && error && <span>{error}</span>}
</Dropzone>
</div>
);
}
验证方法:
export const validateImage = imageList => {
if (imageList) {
if (imageList.length > 1) {
return "You can upload one image at a time";
} else if (imageList.length === 1) {
let selectedImage = imageList[0];
if (!selectedImage.type.match('image.*')) {
return "Only image files are allowed";
} else if (selectedImage.size > 1048576) {
return "Maximum file size exceeded";
}
}
}
};
渲染方法:
render() {
const { handleSubmit } = this.props;
return (
<div>
<form onSubmit={handleSubmit(this._onSubmit.bind(this))}>
<Field name="title" label="Name" type="text" component={renderInputField}/>
<Field name="description" label="Description" type="text" component={renderTextAreaField}/>
<Field name="amount" label="Amount" type="text" component={renderInputField}/>
<Field name="image" component={renderDropzoneField}/>
<button type="submit" className="btn btn-primary">Create</button>
<button type="button" className="btn btn-primary" onClick={this.props.onClose}>Cancel</button>
</form>
{ this.state.error ? <span>{this.state.error}</span> : <noscript/> }
</div>
);
}
当我加载 'pdf' 文件(导致出现错误消息)时,touched
值仍然为 false,error
为 undefiend
。
更新 1
验证在表单级别完成:
const validators = [
{
field: 'title',
validator: validateName
},
{
field: 'description',
validator: validateDescription
},
{
field: 'amount',
validator: validateAmount
},
{
field: 'image',
validator: validateImage
}
];
class NewExpense extends Component {
constructor(props) {
super(props);
this.state = {
error: undefined
};
}
_onSubmit = values => {
let reader = new FileReader();
reader.onloadend = e => {
var imageValue = reader.result;
this.props.createExpense(values, imageValue, this.props.groupId, () => this.props.onClose(), error => this.setState({error: error}));
};
reader.readAsDataURL(values.image[0]);
}
_onImagePreviewChange = files => {
debugger;
}
render() {
const { handleSubmit } = this.props;
return (
<div>
<form onSubmit={ handleSubmit(this._onSubmit.bind(this)) }>
<Field name="title" label="Name" type="text" component={ renderInputField }/>
<Field name="description" label="Description" type="text" component={ renderTextAreaField }/>
<Field name="amount" label="Amount" type="text" component={ renderInputField }/>
<Field onChange={this._onImagePreviewChange.bind(this)} name="image" label="Image" component={ renderDropzoneField } />
<button type="submit" className="btn btn-primary">Create</button>
<button type="button" className="btn btn-primary" onClick={this.props.onClose}>Cancel</button>
</form>
{ this.state.error ? <span>{this.state.error}</span> : <noscript/> }
</div>
);
}
}
export default connect(null, { createExpense })(reduxForm({
validate,
form:'NewExpense',
validators
})(NewExpense));
您是否在提交表单时阻止默认操作的发生?如果不是,页面将刷新并清除触摸和错误状态。
在 handleSubmit(event)
中,您应该包括以下行:
event.preventDefault();
这将防止在单击“提交”时刷新页面。
从您的代码中不清楚您是如何触发验证的(是提交级别还是字段级别?)。不管怎样,我组装了一个沙箱,它可以工作 here。 我所做的是将验证 属性 添加到您的字段
<Field validate={validateImage} name="image" component={renderDropzoneField} />
并使用 dirty
而不是 touch
{dirty &&(error && <span>{error}</span>)}