Gabriel Garrett
Gabriel Garrett

Reputation: 2127

How to make react-native Picker stay at newly selected option?

I have a picker that I'm testing on iOS right now with two options. Every time I drag down from the first option to the second option, the picker immediately returns to the first option.

This is what my the code for my picker looks like.

<Picker 
      style={{
        width: 100,
      }}
      selectedValue={(this.state && this.state.pickerValue) || 'a'}
      onValueChange={(value) => {
        this.setState({value});
      }} itemStyle={{color: 'white'}}>
      <Picker.Item label={'Hello'} value={'a'} />
      <Picker.Item label={'World'} value={'b'} />
</Picker>

I want the selector to stay at the newly scrolled-to option. I've also removed the || 'a' part of the selectedValue attribute but that didn't solve the issue either.

Upvotes: 22

Views: 31026

Answers (3)

Abhishek Kumar
Abhishek Kumar

Reputation: 86

I just came across this and was facing the same issue, the scrolling reaches the new item and resets to the first item. I have done this using stateless component (Hooks):

I have an array of objects as the value and option as key

const data = useState({
"options":[{
"name":"Dish 1","price":0},{"name":"Dish 2","price":0}]})

const [selected, setSelected] = useState(0)

The Picker component:

<PickerIOS
    selectedValue={selected_choice}
    onValueChange={(value, index) => {
            set_selected_choice(index)
          }}
        >
          {data?.map((item, index) => (
            <PickerIOS.Item
              key={item}
              value={index}
              label={item.name}
            />
          ))}
</PickerIOS>

Here, I have stored the index of the array elements in the selected state and have updated it from the PickerIOS Item, keeping the value as index.

Upvotes: 4

Romer Maldonado
Romer Maldonado

Reputation: 1

I used this "hack":

render() {
    const values = ['1', '2'];

    return (
      <Picker
        value={this.state.value}
        onValueChange={this.onValueChange.bind(this)}
      >
      {
                <Picker
                    value={this.state.value}
                    onValueChange={this.onValueChange.bind(this)}
                >
                {
                    [<Picker.Item
                        label="n/a"
                        value={null}
                    />].concat(values.map(value => {
                            return (
                                <Picker.Item
                                    label={value}
                                    value={value}
                                />
                            )
                            })
                    ) 
                }
                </Picker>
    );
  }

Upvotes: -6

Nakib
Nakib

Reputation: 4713

On value change you need to specify which property of the state changed and change it accordingly with this.setState

onValueChange={(value) => {this.setState({pickerValue: value});

Complete Code

<Picker 
      style={{
        width: 100,
      }}
      selectedValue={(this.state && this.state.pickerValue) || 'a'}
      onValueChange={(value) => {
        this.setState({pickerValue: value});
      }} itemStyle={{color: 'white'}}>
      <Picker.Item label={'Hello'} value={'a'} />
      <Picker.Item label={'World'} value={'b'} />
</Picker>

Upvotes: 32

Related Questions