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.
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.
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:
Now when you submit the form it will get passed to formik with the name 'language' and the selected option.
Hope this helped you!