# Figuring out Yup dynamic validation schema - Fri 27th Nov, 2020 In order to create the dynamic form schema, I had to do 3 things: 1. Set the schema into state for later updating: ```typescript= const [validationSchema, setValidationSchema] = useState<ObjectWithSchema>({ // ... Message: yup.object().shape({ message: yup.string().trim().required(t('recognise:validationSchema.message.required')), }), DynamicForm: yup.object().shape({ // form is dynamic and schema will be updated later details: yup.object().shape({}), }), }) ``` (The key here is the name of the screen) 2. Create an empty Yup `object` in the base schema: ```typescript= DynamicForm: yup.object().shape({ // form is dynamic and schema will be updated later details: yup.object().shape({}), }), ``` 3. Use context to expose the schema to the subsequent screen 4. In the dynamic form screen, create and update the schema stored in state: ```typescript= useEffect(() => { // if field is not required, don't validate const requiredElements = (nominationFormElements ?? []).filter((element) => element.validation.some( (validationObj) => validationObj.name === 'required' && element.type !== 'sectionbreak' ) ) // create dynamic schema of required form fields const nominationFormSchema = requiredElements.reduce((acc, curr) => { const requiredValidation = curr.validation.find((validationObj) => validationObj.name === 'required') switch (curr.type) { case 'checkbox': return { ...acc, [curr.id]: yup .array() .min(1, requiredValidation?.message ?? t('recognise:validationSchema.general.required')), } case 'file': return acc default: return { ...acc, [curr.id]: yup .string() .required(requiredValidation?.message ?? t('recognise:validationSchema.general.required')), } } }, {}) // create nomination form inital values for Formik const nominationFormInitialValues = requiredElements.reduce((acc, curr) => { switch (curr.type) { case 'checkbox': return { ...acc, [curr.id]: [], } case 'file': return { ...acc, [curr.id]: '', } default: return { ...acc, [curr.id]: '', } } }, {}) // Set nomination form initial values into formik on mount, otherwise the validation won't work setFieldValue('nominationDetails', nominationFormInitialValues) // update validation schema state setValidationSchema((prevValidationSchema) => ({ ...prevValidationSchema, NominationForm: yup.object().shape({ nominationDetails: yup.object().shape(nominationFormSchema) }), })) }, [nominationFormElements, setValidationSchema, t, setFieldValue]) ``` The whole setup was quite difficult to figure out, but it's good to know how to handle dynamic forms with Formik and Yup. ###### tags: `programmingjournal` `2020` `C+` `nominations` `Formik` `yup` `validation` `dynamic`