I've been trying to make Picker component of React-Native work for Formik for last three days but getting into issues one after another. After lots of googling around and reading documents, I've come up with below code. This code loads the Picker. But when I select an item from the Picker, I am getting a "Cannot read property 'type' of undefined error." I need urgent help to get this figured out. Please help.

import React, { Component, Fragment } from 'react';
import * as yup from 'yup'
import { Formik } from 'formik'
import { View, Button, Alert, Picker } from 'react-native';
export default class TestPickerFormik extends React.Component {
constructor(props) {
super(props);
this.state = {
hasError: false,
errorText: '',
selectedBank:0,
};
}
handleSubmit = () => {
Alert.alert('Welcome');
};
render() {
return (
<View style={{ flex: 1, alignItems: 'center' }}>
<Formik
initialValues={{ bank: '' }}
onSubmit={this.handleSubmit}
validationSchema={yup.object().shape({
bank: 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 bank'}
itemStyle={{ backgroundColor: "grey" }}
selectedValue={values.bank}
onValueChange={(handleChange('bank'))}>
<Picker.Item label='Select your bank' value={0} key={0} />
<Picker.Item label='SBI' value={1} key={1} />
<Picker.Item label='CITI' value={2} key={2} />
<Picker.Item label='ICICI' value={3} key={3} />
</Picker>
</View>
<Button title='Submit' onPress={handleSubmit} />
</Fragment>
)}
</Formik>
</View>
)
}
}
I need urgent help to get this figured out. Please help.
I think there is an issue about picker behaviour and formik expectations:
onValueChange is called with two args instead of one for onChangeText. (https://facebook.github.io/react-native/docs/picker#onvaluechange)
Try something like:
<Picker style={{ height: 40, width: 400 }}
mode='dropdown'
prompt={'Select bank'}
itemStyle={{ backgroundColor: "grey" }}
selectedValue={Number(values.bank)}
onValueChange={(...args) => handleChange('bank')(String(args[1]))}>
<Picker.Item label='Select your bank' value={0} key={0} />
<Picker.Item label='SBI' value={1} key={1} />
<Picker.Item label='CITI' value={2} key={2} />
<Picker.Item label='ICICI' value={3} key={3} />
</Picker>
Be careful if you use formik with validation onBlur because picker does not have onBlur prop.
onValueChange={(...args) => {
handleChange('bank')(String(args[1]));
setFieldTouched('bank', true);
}}>
I've been having a similar issue but with the <Switch /> component.
I think the root of this problem is that handleChange expects a String, I noticed the values in your picker were numbers so potentially the same issue
Included in a new umbrella issue. The workaround described above will work but we should make note of this in the docs. It would be good to perhaps make an “all inputs” React Native example.
Just stumbled upon same issue and I think using setFieldValue would be better practice since then you don't bother with type conversion e.g. string to int, boolean vice versa and also you keep desired data type on your form values. Though being all that said 1.5.x is perfectly handling types other than string so it would be nice to keep it that way.
We could try:
/component/AppInputs.js
export const AppPickerInput = ({ formikProps, formikKey, labelText, options=[] , ...rest}) => {
return (
<FieldWrapper
formikKey={formikKey}
labelText={labelText}
formikProps={formikProps}>
<View style={styles.PickerContainerStyle}>
<Picker
itemStyle={{ color: 'red' }}
selectedValue={ value => {
formikProps.setFieldValue(formikKey, value)
} }
onValueChange={ value => {
formikProps.setFieldValue(formikKey, value)
}}
{...rest}
>
{
options.map( item => (
<Picker.Item label={item.label} value={item.value} />
))
}
</Picker>
</View>
</FieldWrapper>
);
}
Then usage in another component after import
import { AppPickerInput } from './../path/components/AppInputs';
const MyApp = () => {
const gender = [
{label: 'Male', value: 'Male'},
{label: 'Female', value: 'Female'}
];
return (
...
<Formik
initialValues={{ gender: "" }}
onSubmit={ (val, actions) => {
setTimeout( () => {
alert("Submitted! "+JSON.stringify(val));
}, 1000);
} }
validationSchema={validateEditPofile}
>
{ formikProps => (
...
<AppPickerInput
formikProps={formikProps}
formikKey="gender"
selectedValue={formikProps.values.gender}
labelText="Gender"
options = {gender}
/>
...
)
}
</Formik>
...
);
}
Hope that helps. :-)
Most helpful comment
I've been having a similar issue but with the
<Switch />component.I think the root of this problem is that
handleChangeexpects a String, I noticed the values in your picker were numbers so potentially the same issue