This is a simplification of the code but I have several pickers and they don't work correctly for me, I don't know what I'm doing wrong.
import { Picker } from '#react-native-picker/picker';
export default function ProfileScreen() {
const [ province, setProvince ] = useState("madrid")
return (
<>
<View style={styles.picker_and_inputs}>
<Picker
selectedValue={province}
onValueChange={(value, itemIndex) => setProvince({value})}
mode="dropdown"
>
<Picker.Item label="Madrid" value="madrid" />
<Picker.Item label="Barcelona" value="barcelona" />
<Picker.Item label="Cataluña" value="cataluña" />
</Picker>
</View>
</>
);
}
I consoled logged what onValueChange was returning
onValueChange={(value, itemIndex) => console.log(value)}
and got a string
madrid
Thus all you need to do is change from this
onValueChange={(value, itemIndex) => setProvince({value})}
to this.
onValueChange={(value, itemIndex) => setProvince(value)}
Everything works fine now just remove those brackets.Full Example here (https://snack.expo.dev/#heytony01/insane-pretzel)
Related
I have created a signup form in react native with formik and yup.According to the documentation I have added the react native picker.
<Formik
initialValues={{ password: '', first_name: '', email: '', passwordConfirmation: '' }}
onSubmit={values => handleSubmit(values)}
validationSchema={registerSchema}
>
{({ handleChange, handleBlur, handleSubmit, values, touched, errors }) => (
<View>
<TextInput
style={styles.textInputTop}
onChangeText={handleChange('first_name')}
onBlur={handleBlur('first_name')}
value={values.first_name}
label="First Name"
mode="outlined"
/>
<Text style={styles.errorMsg}>{touched.first_name && errors.first_name}</Text>
//Other Fields I have not mentioned in the code
<View style={styles.pickerContainer}>
<Text style={styles.depText}>Department</Text>
<Picker
style={{ height: 50, width: 150 }}
onValueChange={(itemValue, itemIndex) => setdepartment(itemValue)}
mode={"dropdown"}
>
<Picker.Item label="Management" value="Management" />
<Picker.Item label="HR" value="HR" />
<Picker.Item label="Accounting" value="Accounting" />
<Picker.Item label="Sales" value="Sales" />
</Picker>
</View>
<Button style={styles.btn} mode="contained" onPress={handleSubmit}>
<Text style={{ color: "white" }}>Sign Up</Text>
</Button>
</View>
)}
</Formik>
I need to add formik and yup to the picker to make it a required field. How do I do it?
If it is not possible with formik and yup, then how I can make the picker required.
on the registerSchema make:
department: Yup.string().required('this field is required')
department will hold the selected value from the picker, you may change the type from string to array depending on the selected value.
before installing Formik, my input looked like so:
const [search, setSearch] = useState('');
....
<View style={styles.profileEditContainer__top}>
<TextInput
style={styles.profileEditContainer__form}
autoCapitalize="none"
placeholder="Enter what you want to create.."
placeholderTextColor={Colors.formPlaceHolderDefault}
name="search"
type="search"
value={search}
onChangeText={(e) => setSearch(e)}
autoCorrect={false}
defaultValue={search}
/>
<Button
disabled={!search}
title="Create"
onPress={(e) => {
createNewCar(e);
}}
/>
</View>
in onChangeText, I would set every character I typed to a state prop called search. With every key that I typed, an API called would be made to get some data from the db.
for example:
if I typed h into the input, the db would return 2 cars honda, hyundai
I read that Formik can simplify a lot of the form setup in React, so I downloaded it, however, the handleChange prop from Formik wants to keep track of values.search
<Formik
initialValues={{
search,
}}
onSubmit={(values) => {
console.log('values', values);
}}>
{({ handleChange, handleSubmit, values }) => (
<View style={styles.profileEditContainer__top}>
<TextInput
style={styles.profileEditContainer__form}
autoCapitalize="none"
placeholder="Enter what you want to create.."
placeholderTextColor={Colors.formPlaceHolderDefault}
autoCorrect={false}
value={values.search}
onChangeText={(e) => {
handleChange(values.search);
setSearch(e);
}}
/>
<Button
disabled={!search}
title="Create"
onPress={handleSubmit}
/>
</View>
)}
</Formik>
Now I can't type into the form because value is pointing at values.search instead of search like it did originally.
Question
How do I fire setSearch in onChangeText but also add search into the formik values prop?
you can make use of setFieldValue('search', e.target.value) instead of handleChange() change the code to the following:
<Formik
initialValues={{
search,
}}
onSubmit={(values) => {
console.log('values', values);
}}>
{({ handleChange, handleSubmit, values, setFieldValue }) => (
<View style={styles.profileEditContainer__top}>
<TextInput
style={styles.profileEditContainer__form}
autoCapitalize="none"
placeholder="Enter what you want to create.."
placeholderTextColor={Colors.formPlaceHolderDefault}
autoCorrect={false}
value={values.search}
onChangeText={(e) => {
//handleChange(values.search);
setFieldValue('search', e.target.value)
setSearch(e);
}}
/>
<Button
disabled={!search}
title="Create"
onPress={handleSubmit}
/>
</View>
)}
</Formik>
i am trying to render a picker with dynamic data from api. but it is giving error
<Picker style={styles.pickerStyleClass}
enabled={true} mode="dropdown"
selectedValue={(this.state.selectedWeight) || "Status"} prompt="Transaction Type"
onValueChange={(itemValue, itemIndex) => this.PickerDataSelection(itemIndex, itemValue)}
itemStyle={{ color: Colors.textColor }}>
{stockQty.map((data) => { <Picker.Item label={data} value={data} /> })}
</Picker>
let stockQty = ["Test1","Test2"];
The only thing missing here that causes this error is return so replace the Picker.Item line to
{stockQty.map((data) => { return <Picker.Item label={data} value={data} /> })}
as nothing was being returned from the function and Picker is made in a way that you can't return anything other than Picker.Item with the required props. Even the following line gives the same error.
{ this.state.someCheck && <Picker.Item label='some' value='value' /> }
and key should also be added as prop in Picker.Item.
I have come across this error when I used Picker component as follows,
<Picker
style={{ flex: 1 }}>
selectedValue={this.props.shift}
onValueChange={value => this.props.employeeFormAction({
prop:'shift', value })}
>
<Picker.Item label='Monday' value='Monday' />
<Picker.Item label='Tuesday' value='Tuesday' />
<Picker.Item label='Wednesday' value='Wednesday' />
<Picker.Item label='Thursday' value='Thursday' />
<Picker.Item label='Friday' value='Friday' />
<Picker.Item label='Saturday' value='Saturday' />
<Picker.Item label='Sunday' value='Sunday' />
</Picker>
I have tired this solution from same community
react-native - Picker - undefined is not an object (evaluating 'this.props.children[position].props)
But it didn't work for me. Could any body suggest solution for this issue.
Try to not hardcode the values. This way is cleaner:
// inside your component (supposing is not a functional component)
_renderShifts = () => {
const shifts = ['Monday', 'Tuesday', 'Wednesday','Thursday',
'Friday','Saturday', 'Sunday'];
return shifts.map((shift) => {
<Picker.Item key={"shift_"+i} label={shift} value={shift} />
});
}
// now your picker should render this way
_renderPicker = () => {
<Picker
style={{ flex: 1 }}>
selectedValue={this.props.shift}
onValueChange={value => this.props.employeeFormAction({prop:'shift', value })}
>
{this._renderShifts()}
</Picker>
}
This error is also returned when the Picker is imported without the corresponding object destructuring.
Incorrect
import Picker from '#react-native-community/picker'
Correct
import { Picker } from '#react-native-community/picker'
Do you know how to set the inital value of React-Native Picker component to empty. I mean it should not show any item selected.
I solved this problem by setting fake unselectable item with value={-1}. Then when user picks valid item,fake item with value={-1} disappear.
// this.state.selectedIndex initially setted to -1
<Picker
selectedValue={this.state.selectedIndex}
onValueChange={(value, index) => { this.setState({selectedIndex: index})
}}
>
// first fake item
if(Platform.OS === 'android' && this.state.selectedIndex === -1) {
<Picker.Item label={'CANCEL'} value={-1} />
}
<Picker.Item label={'First'} value={1} />
<Picker.Item label={'Second'} value={2} />
<Picker.Item label={'Third'} value={3} />
</Picker>
I think the part you need is enabled={false}.
https://github.com/react-native-picker/picker#enabled-1
<Picker
selectedValue={selected}
onValueChange={(itemValue, itemIndex) => setSelected(itemValue)}>
<Picker.Item key='' label='-- Select a Item --' value={null} enabled={false} />
{items.map(i => <Picker.Item key={i.key} label={i.label} value={i.value} />)}
</Picker>
you can do it this way
<Picker
selectedValue={selected}
onValueChange={itemValue => setSelected(itemValue)}
>
{items &&
items.map((element, index) => {
if (index === 0) {
return (
<Picker.Item
key={element.value}
label={element.label}
value={element.value}
enabled={false}
/>
);
}
return (
<Picker.Item
key={element.value}
label={element.label}
value={element.value}
/>
);
})}
</Picker>