Javascript 福米克公司;yup表单验证在VirtualizedSelect中未按预期工作
为了进行表单验证,我使用formik创建了一个表单。 我已经使用了组件Formik、Form、Field Form Form Formik并对它们进行了配置:Javascript 福米克公司;yup表单验证在VirtualizedSelect中未按预期工作,javascript,reactjs,react-select,formik,Javascript,Reactjs,React Select,Formik,为了进行表单验证,我使用formik创建了一个表单。 我已经使用了组件Formik、Form、Field Form Form Formik并对它们进行了配置: import { Formik, Form, Field } from "formik"; import { object, string } from "yup"; import isEmpty from "lodash/isEmpty"; import FormikSelectInput from ".
import { Formik, Form, Field } from "formik";
import { object, string } from "yup";
import isEmpty from "lodash/isEmpty";
import FormikSelectInput from "../common/FormikSelectInput";
class App extends Component {
render() {
const options = this.props.categories.map(c => {
return { label: c.name, value: c.name };
});
return (
<Formik
validationSchema={object().shape({
category: string().required("Category is required.")
})}
initialValues={this.props.obj}
onSubmit={(values, actions) => {
console.log(values);
}}
render={({ errors, dirty, isSubmitting, setFieldValue }) => (
<Form>
<Field
name="category"
label="Categories"
value={this.props.obj.category.name}
options={options}
component={FormikSelectInput}
/>
<button
type="submit"
className="btn btn-default"
disabled={isSubmitting || !isEmpty(errors) || !dirty}
>
Save
</button>
</Form>
)}
/>
);
}
}
//Prop Types validation
App.propTypes = {
obj: PropTypes.object.isRequired,
categories: PropTypes.array.isRequired,
actions: PropTypes.object.isRequired
};
const getElementByID = (items, id) => {
let res = items.filter(l => l.id === id);
return res.length ? res[0] : null; //since filter returns an array we need to check for res.length
};
//Redux connect
const mapStateToProps = ({ objects, categories }, ownProps) => {
let obj = {
id: "",
name: "",
category: { id: "", name: "" }
};
return {
obj: getElementByID(objects, ownProps.match.params.id) || obj,
categories: categories
};
};
export default connect(
mapStateToProps,
{...}
)(App);
从“Formik”导入{Formik,Form,Field};
从“yup”导入{object,string};
从“lodash/isEmpty”导入isEmpty;
从“./common/FormikSelectInput”导入FormikSelectInput;
类应用程序扩展组件{
render(){
const options=this.props.categories.map(c=>{
返回{label:c.name,value:c.name};
});
返回(
{
console.log(值);
}}
render={({errors,dirty,isSubmitting,setFieldValue})=>(
拯救
)}
/>
);
}
}
//道具类型验证
App.propTypes={
obj:PropTypes.object.isRequired,
类别:PropTypes.array.isRequired,
操作:PropTypes.object.isRequired
};
常量getElementByID=(项,id)=>{
让res=items.filter(l=>l.id==id);
return res.length?res[0]:null;//由于过滤器返回数组,我们需要检查res.length
};
//重复连接
常量mapStateToProps=({objects,categories},ownProps)=>{
设obj={
id:“”,
姓名:“,
类别:{id:,名称:}
};
返回{
obj:getElementByID(对象,ownProps.match.params.id)| | obj,
类别:类别
};
};
导出默认连接(
MapStateTops,
{...}
)(App);
我有一个自定义组件“FormikSelectInput”:
import React, { Component } from "react";
import classnames from "classnames";
import VirtualizedSelect from "react-virtualized-select";
import "react-select/dist/react-select.css";
import "react-virtualized/styles.css";
import "react-virtualized-select/styles.css";
const InputFeedback = ({ children }) => (
<span className="text-danger">{children}</span>
);
const Label = ({ error, children, ...props }) => {
return <label {...props}>{children}</label>;
};
class FormikSelectInput extends Component {
constructor(props) {
super(props);
this.state = { selectValue: this.props.value };
}
render() {
const {
field: { name, ...field }, // { name, value, onChange, onBlur }
form: { touched, errors }, // also values, setXXXX, handleXXXX, dirty, isValid, status, etc.
className,
label,
...props
} = this.props;
const error = errors[name];
const touch = touched[name];
const classes = classnames(
"form-group",
{
"animated shake error": !!error
},
className
);
console.log("props", props);
return (
<div className={classes}>
<Label htmlFor={name} error={error}>
{label}
</Label>
<VirtualizedSelect
name={name}
id={name}
className="form-control"
{...field}
{...props}
onChange={(selectValue) => this.setState(() => {
this.props.form.setFieldValue('category',selectValue)
return { selectValue }
})}
value={this.state.selectValue}
/>
{touch && error && <InputFeedback>{error}</InputFeedback>}
</div>
);
}
}
export default FormikSelectInput;
import React,{Component}来自“React”;
从“类名”中导入类名;
从“反应虚拟化选择”导入虚拟化选择;
导入“react-select/dist/react-select.css”;
导入“react virtualized/styles.css”;
导入“react virtualized select/styles.css”;
常量输入反馈=({children})=>(
{儿童}
);
常量标签=({error,children,…props})=>{
返回{children};
};
类FormikSelectInput扩展了组件{
建造师(道具){
超级(道具);
this.state={selectValue:this.props.value};
}
render(){
常数{
字段:{name,…field},//{name,value,onChange,onBlur}
表单:{toucted,errors},//还有值,setXXXX,handlexxx,dirty,isValid,status,等等。
类名,
标签,
…道具
}=这是道具;
常量错误=错误[名称];
const touch=触摸[名称];
常量类=类名(
“表格组”,
{
“动画抖动错误”:!!错误
},
类名
);
控制台日志(“道具”,道具);
返回(
{label}
此.setState(()=>{
this.props.form.setFieldValue('category',selectValue)
返回{selectValue}
})}
value={this.state.selectValue}
/>
{touch&&error&&{error}
);
}
}
导出默认FormisSelectInput;
我的组件正在工作,我可以选择一个选项,但是为什么当我清空select字段时,formik和“yup”验证会向我显示一个错误呢
当我清除选择字段时,我得到一个错误-'类别必须是字符串
类型,但最终值是:null
。如果“null”是空值,请确保将架构标记为.nullable()
'
我的代码基于。字段似乎希望根据您的
validationSchema需要字符串
这个错误为我指明了正确的方向。以下是Yup.nullable()
的文档:
尝试将.nullable()添加到验证链中
validationSchema={object().shape({
类别:string().required(“类别是必需的”).nullable()
})}
希望这有帮助。
谢谢,这确实有帮助,但我现在有另一个问题。尽管字段为空,表单上的按钮仍处于启用状态。我添加了一张关于它的图片。解决了上一个问题,我对初始值进行了如下编辑:initialValues={{…this.props.obj,category:“}}}这是因为在this.props.obj中category是一个对象,而不是空字符串。(这个.props.obj来自redux商店)。Mat-“mwarger”,非常感谢您的帮助,您关于formik的帖子非常棒。我喜欢它。干杯