quirky purple
quirky purple

Reputation: 2219

Picker onValueChange not being called on every selection

I have a picker with some hard coded values. On value change I want to update my redux store with the selected value using an action creator function from my store. I am running into an issue however where the onValueChange listener does not appear to be called for every selection change.

Picker code

<Picker selectedValue={this.props.settings.colorScheme} 
  onValueChange={(value, itemIndex) => this.props.onValueChange({prop: 'colorScheme', value})}>
  <Picker.Item value="blue" label="Blue"/>
  <Picker.Item value="green" label="Green"/>
  <Picker.Item value="orange" label="Orange"/>
  <Picker.Item value="purple" label="Purple"/>
  <Picker.Item value="red" label="Red"/>
</Picker>

Method passed into component to handle value change. I set breakpoints here but they only trigger typically for every other selection. Start on blue, then choose orange it fires. Then choose green and it doesn't fire, but then choose red and it will fire again.

handleValueChange({prop, value}) {
    this.props.updateSettings({prop, value})
}

Here is my redux action creator

export function updateSettings ({prop, value}) {
  return {
    type: UPDATE_SETTINGS,
    payload: ({ prop, value }),
  }
}

My render method (where onValueChange becomes handleValueChange)

render() {
  return (
    <Settings
    settings={this.props.settings}
    onValueChange={this.handleValueChange.bind(this)}
    />
  )
}

Upvotes: 4

Views: 6508

Answers (1)

ThaJay
ThaJay

Reputation: 1942

I have found the folowing workaround using componentDidUpdate:

export default class PickerComponent extends PureComponent {
  constructor (props) {
    super(props)
    this.state = {value:this.props.eventId}
  }

  componentDidUpdate () {
    if (this.props.eventId !== this.state.value) {
      this.props.chooseEvent(this.state.value)
    }
  }

  onValueChange = value => {
    if (value) this.setState({value})
  }

  makePickerItem (label, key) {
    const props = {label, key, value:key}
    return <Picker.Item {...props} />
  }

  makePickerItems = function * () {
    for (let id in this.props.things) {
      yield this.makePickerItem(this.props.things[id].name, eventId)
    }
  }

  render () {
    return (
      <Picker
        selectedValue={this.state.value}
        onValueChange={this.onValueChange}
      >
        {[...this.makePickerItems()]}
      </Picker>
    )
  }
}

Upvotes: 1

Related Questions