---
# System prepended metadata

title: 'Continuing with components for dynamic React Native form, dynamic form validation - Wed, Thurs 25th-26th Nov, 2020'
tags: [C+, validation, checkbox, dynamic, Formik, switch, form, programmingjournal, '2020', yup, nominations]

---

# Continuing with components for dynamic React Native form, dynamic form validation - Wed, Thurs 25th-26th Nov, 2020

These last couple of days I have continued building out the screen and component needed to show a dynamic list of form fields in C+.

Checkbox.tsx looks something like this:
```typescript=
export const Checkbox: React.FC<CheckboxProps> = ({
    colorScheme = 'dark',
    checked = false,
    onValueChange,
    size = 'sm',
    ...props
}) => {
    const [isChecked, setIsChecked] = useState(checked)
    useEffect(() => {
        setIsChecked(checked)
    }, [checked])

    const { colors } = useTheme()

    const handleChange = () => {
        setIsChecked((prevState) => {
            onValueChange && onValueChange(!prevState)
            return !prevState
        })
    }
    return (
        <CheckboxOuter
            size={size}
            colorScheme={colorScheme}
            onPress={handleChange}
            accessibilityRole="checkbox"
            accessibilityState={{ checked: isChecked }}
            {...props}
        >
            <>{isChecked && <Checkmark color={colors.green} size={sizes[size] * 0.8} />}</>
        </CheckboxOuter>
    )
}
```

As before, I'm using Formik to manage things like form values, touched fields, etc, and Yup for validation. Fortunately, the validation I receive from the API is usually quite simple. I'm updating my Yup schema thusly:

```typescript=
useEffect(() => {
    // if field is not required, don't validate
    const requiredElements = (nominationFormElements ?? []).filter((element) =>
        element.validation.some((validationObj) => validationObj.name === 'required')
    )

    // 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 ?? 'This field is required'),
                }
            case 'file':
                return acc
            default:
                return {
                    ...acc,
                    [curr.id]: yup.string().required(requiredValidation?.message ?? 'This field is required'),
                }
        }
    }, {})

    // validation schema is stored in state, update
    setValidationSchema((prevValidationSchema) => ({
        ...prevValidationSchema,
        NominationForm: yup.object().shape(nominationFormSchema),
    }))
}, [nominationFormElements, setValidationSchema])
```

Formik is great, but since [this is React Native](https://formik.org/docs/guides/react-native), it's as straightforward as HTML forms. For some fields (such as a `TextInput`), you can simply pass Formik's `handleChange` method straight. For others (such as my checkbox or a `switch`), since Formik expects a React change event, and the `switch` only exposes a boolean value, you have to manage the value change yourself using `setFieldValue`. It's not bad, just something to be aware of.

###### tags: `programmingjournal` `2020` `C+` `nominations` `Formik` `yup` `validation` `dynamic` `checkbox` `switch` `form`