'How to assign object validation in yup for react-select (single-select)

I am trying to implement validation for react-select (single-select) using yup concept. But i am getting this error:

Objects are not valid as a React child (found: object with keys {label, value}). If you meant to render a collection of children, use an array instead.

I want to know how to assign objects in validation schema for yup concept

<Formik
  initialValues={{
    department:"",
  }}
  onSubmit={this.submitForm}
  validationSchema={Yup.object().shape({
    department: Yup.object().shape({
      label: Yup.string().required(),
      value: Yup.string().required(),
    }),
})}>
{ props => {
  const {
    values,
    touched,
    errors,
    isSubmitting,
    handleChange,
    handleBlur,
    handleSubmit,
    selectedOption
  } = props;
  return (
    <React.Fragment>

    <InputLabel shrink htmlFor={'department'}>
    Department</InputLabel>
    <Select
          inputId="department"
          options={options}
          value={values.department}
          onChange={this.onChangeOption}
          onBlur={handleBlur}         
       />
{errors.department && touched.department && ( {errors.department} )} 
Submit </div> </React.Fragment> ); }} 


Solution 1:[1]

I want to know how to assign objects in validation schema for yup concept

You did it correct (as far as I can tell):

validationSchema={Yup.object().shape({
  department: Yup.object().shape({
    label: Yup.string().required(),
    value: Yup.string().required(),
  })
}

What React complains about is this line:

{errors.department && touched.department && ( {errors.department} )} 

What this evalautes to is if errors has a key called department and if touched has a key called department then render the object errors.department. React can't do that. If you want to display the errors you I suggest having a dedicated component (e.g. a <p> tag) for it outside of your select. Something like this:

{errors.department && touched.department && (<p>{errors.department.label}</p>)}

You can do something similar for value.

PS: Your code seems incomplete and poorly formatted (e.g. there is a floating <div /> tag).

Solution 2:[2]

You can refine the shape schema with nullable() and required().

Example

const requiredOption = Yup.object()
  .shape({
    value: Yup.string(),
    label: Yup.string(),
  })
  .nullable()
  .required('This field is required.');

Why nullable() and required() to the shape!

  1. If an input is focused and the user decides to skip the input, a value for that input is still set to null and the validation is triggered. Eventually, you would end up with an error like this.

input must be an object type, but the final value was: null. If "null" is intended as an empty value be sure to mark the schema as .nullable()

  1. Instead of having required on individual properties of shape schema, if you are sure all the properties are mandatory, the required function can be called on the object shape directly.

Solution 3:[3]

Little tweak from above comment of Hesters.

    validationSchema={Yup.object().shape({
        valueToBeChange: Yup.object().shape({
           label: Yup.string().required('label is required'),
           value: Yup.string().required('value is required'),
        })
     }

On the front end I have added condition

    (valueToBeChange?.label?.message && valueToBeChange?.label?.message) 
&& (valueToBeChange?.value?.message && valueToBeChange?.value?.message)

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 J. Hesters
Solution 2 Deepak Kadarivel
Solution 3 Mudassir Kidwai