Formik & yup form validation not working as expected with VirtualizedSelect
It looks like the field is expecting the string to be required based on your validationSchema
.
The error helped point me in the right direction. Here's the docs for Yup .nullable()
: https://github.com/jquense/yup#mixednullableisnullable-boolean--true-schema
Try adding .nullable() to the chain of validations.
validationSchema={object().shape({
category: string().required("Category is required.").nullable()
})}
Kamran
Updated on July 09, 2022Comments
-
Kamran almost 2 years
I created a form with formik in order to have form validations. I have used the components Formik, Form, Field form formik and configured them:
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);
And I have a custom component '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;
My component is working and I am able to select an option, but why formik together with 'yup' validation showing me an error when I empty the select field.
When I clear my select field I get an ERROR - 'category must be a
string
type, but the final value was:null
. If "null" is intended as an empty value be sure to mark the schema as.nullable()
'My code is based on the this example.