React Native – How to work with form (1)? Formik & Yup

What does Formik do?

  • Track form state
  • Handles form submission
  • Handles validation and error messages

Install

yarn add formik yup

Usage template

const ExampleComponent = () => {
    const validationSchema = Yup.object().shape({
        company: Yup.string()
            .required('Select a company'),
        employee: Yup.object()
            .typeError('Select an employee')
            .required('Select an employee'),
        newName: Yup.string()
            .required('Enter a valid name')
            .min(2, 'Name must have at least 2 characters')
    })

    const onSubmit = async (values, {setSubmitting, setErrors, setStatus, resetForm, setFieldValue}) => {
        
            // Work with values
            // ....

            // Reset form
            resetForm({})
            setFieldValue('company', values.company)
            setStatus({success: true})

        } catch(error) {
            setStatus({success: false})
            setSubmitting(false)
            setErrors({submit: error.message})
        }
    }

    return <>
        <Formik
            initialValues={
                {
                    company: '',
                    employee: null,
                    newName: ''
                }
            }
            onSubmit={onSubmit}
            validationSchema={validationSchema}>
            {({ setFieldValue, handleSubmit, values, errors, isValid, touched }) => (
                <>
                    <Text style={{ color: 'red' }}>{errors.company}</Text>
                     <SelectCompany
                        selectedCompany={values.company}
                        setFieldValue={setFieldValue}
                        companyList={companyList} />
                    
                    ...
                    
                    <ButtonSubmit 
                        onClick={handleSubmit}
                        disabled={!isValid} // Disable Button when form is not valid
                        title={'Submit'}/>
                </>
            )}
        </Formik>
    </>
}

export default ExampleComponent

How to reset form after submit?

// Reset form
resetForm({})

// Keep value for only 1 field (other fields are reset)
setFieldValue('company', values.company)

How to “setFieldValue” for different fields at the same time?

When “setFieldValue” for a field and reset another filed at the same time like this, Yup will still set error for first field

setFieldValue('company', val)
setFieldValue('employee', null)

You need to do like this

setFieldValue('company', val)
setTimeout(() => setFieldValue('employee', null))

How to show error message only when pressing Submit?

// Change
<Text style={{ color: 'red' }}>{errors.company}</Text>

// To
<Text style={{ color: 'red' }}>{touched.company && errors.company}</Text>

How to disable submit button when form is not valid

{({ ... isValid ... }) => (
...
<ButtonSubmit 
    onClick={handleSubmit}
    disabled={!isValid} // Disable Button when form is not valid
    title={'Submit'} />

How to update “initialValues” outside form?

<Formik
        enableReinitialize
        initialValues={props.initialValues}
...

Use “enableReinitialize“. enableReinitialize doesn’t change anything.

  • If form hasn’t been touched (dirty = false) the form is re-rendered if any property in initialValues is changed from outside of Formik
  • Once the form is changed by any user input (dirty = true), changes to the initialValues triggers the render function but does not re-write the values within the form

How to “setFieldValue” from “useEffect”?

 const formikRef = useRef()

 useEffect = (() => {
      ....
      if (formikRef.current) {
          formikRef.current.setFieldValue(
              "keyName",
              value
          )
      }
      ...
 })
 ...
 <Formik
        innerRef={formikRef}
        initialValues={initialValues}
        validationSchema={validSchema}
        onSubmit={onSubmit}>

Be the first to comment

Leave a Reply

Your email address will not be published.


*