Formik: Form Validation WIth Formik and React Native

Created on 14 Mar 2019  路  6Comments  路  Source: formium/formik

鉂換uestion

I am learning to build app using react-native and one of my screens has couple of Picker components. I want to run some basic validations on them before submitting. I want to make sure value of Picker is not null. I'm trying to use Formik for this and getting little confused. My code looks like this(stripped down):

<View style={{flex:1, alignItems:'center'}}>
<Formik
initialValues={{ language: ''}}
onSubmit={this.handleSubmit}
validationSchema={yup.object().shape({
language: yup
    .string()
    .required()
})}>
{({ values, handleChange, errors, setFieldTouched, touched, isValid, handleSubmit }) => (
<Fragment>
    <View style={{borderRadius: 3, borderWidth: 1}}>
        <Picker style={{ height: 40, width: 400}}
            mode='dropdown'
            prompt={'Select language'}
            itemStyle={{ backgroundColor: "grey"}}
            selectedValue={this.state.selectedLanguage}
            onValueChange={(itemValue, itemIndex) => 
                this.setState({selectedLanguage: itemValue})}>
                <Picker.Item label='Select your language' value={null} key={0}/>
                <Picker.Item label='Java' value={1} key={1}/>
                <Picker.Item label='Python' value={2} key={2}/>
                <Picker.Item label='Scala' value={3} key={3}/>
        </Picker>
    </View>

    <Button title='Submit' onPress={() => {
    this.handleSubmit()
    }}/>
</Fragment>
)}



Questions I have: How will Formik map to my Picker component. I am not passing any name. How do I pass the name(Language) to Picker. Can I validate non-null value for selectedValue before submitting?

Seriously, for immediate help, just ask your question on the #formik channel on Reactiflux.

Most helpful comment

The formik bag has a prop named "setFieldValue", with this you can use it in your onValueChange prop of your picker like this:

onValueChange={(itemValue, itemIndex) => {
    setFieldValue('langauge', itemValue)
    this.setState({selectedLanguage: itemValue})
}

Now when you submit the form it will get passed to formik with the name 'language' and the selected option.

Hope this helped you!

All 6 comments

The formik bag has a prop named "setFieldValue", with this you can use it in your onValueChange prop of your picker like this:

onValueChange={(itemValue, itemIndex) => {
    setFieldValue('langauge', itemValue)
    this.setState({selectedLanguage: itemValue})
}

Now when you submit the form it will get passed to formik with the name 'language' and the selected option.

Hope this helped you!

The formik bag has a prop named "setFieldValue", with this you can use it in your onValueChange prop of your picker like this:

onValueChange={(itemValue, itemIndex) => {
    setFieldValue('langauge', itemValue)
    this.setState({selectedLanguage: itemValue})
}

Now when you submit the form it will get passed to formik with the name 'language' and the selected option.

Hope this helped you!

Thanks, it's very helpful, but after i call onSubmit I reset field using actions.resetForm(); it does not reset the Picker :\ How can i Solve it?

@anastely in the snippet above, you aren't providing the value to the picker from Formik.
In the above, remove language from the state of your component altogether (even if temporarily).

Managing values outside of Formik is bound to cause the values to go out of sync. Instead, try something like this:

const yupSchema = yup.object().shape({
    language: yup
        .string()
        .required()
});

const initialValues = {
    language: '',
}

// in your form
    <View>
        <Formik
            initialValues={initialValues}
            validationSchema={yupSchema}
            onSubmit={this.handleSubmit}
        >
            {formik => (
                <Fragment>
                    <View>
                        <Picker
                            // passing value directly from formik
                            selectedValue={formik.values.language}
                            // changing value in formik
                            onValueChange={itemValue => formik.setFieldValue('language', itemValue)}
                        >
                            <Picker.Item label='Select your language' value={initialValues.language} key={0} />
                            <Picker.Item label='Java' value={1} key={1} />
                            <Picker.Item label='Python' value={2} key={2} />
                            <Picker.Item label='Scala' value={3} key={3} />
                        </Picker>
                    </View>

                    { /* submitting formik instead of calling this.handleSubmit directly */ }
                    <Button title='Submit' onPress={formik.handleSubmit} />
                </Fragment>
            )}
        </Formik>
    </View>
// end your form

@johnrom very well, Thank you

@johnrom following your implementation, my form resets (scrolls back to top) on select. I don't define any class state, only whatever initalValues formik provides..any idea why?

@rostgoat I'm sorry I'm not super familiar with React Native, but if you're able to create a codesandbox repro I'll try and see if I can figure out what's going on.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

green-pickle picture green-pickle  路  3Comments

outaTiME picture outaTiME  路  3Comments

najisawas picture najisawas  路  3Comments

Jungwoo-An picture Jungwoo-An  路  3Comments

PeerHartmann picture PeerHartmann  路  3Comments