danielweinmann / react-native-picker-dropdown

A dropdown that uses React Native's Picker for Android and ActionSheetIOS for iOS
MIT License
28 stars 20 forks source link

Mixing hard coded and looped children causes error #6

Open dave-irvine opened 6 years ago

dave-irvine commented 6 years ago

Hi,

Just stumbled across this issue where I want to provide children to the Picker by map()'ing an array to Picker.Items

const alphabet = 'abcdefghijklmnopqrstuvwxyz'.split('');

<Picker
  selectedValue={this.state.letterA}
  onValueChange={this.onValueChange}
  mode='dialog'
>
  <Picker.Item label="Please select" value='none' />
  {
    alphabet.map((letter) => {
      return (
        <Picker.Item label={letter} value={letter} />
      );
    })
  }
</Picker>

This is causing an error here: https://github.com/danielweinmann/react-native-picker-dropdown/blob/master/Picker.js#L34 due to the 2nd element in the children array being an array of the 26 Picker.Item elements.

If I remove the hard coded Picker.Item as follows, everything is fine, I'm just missing my default value Picker.Item

<Picker
  selectedValue={this.state.letterA}
  onValueChange={this.onValueChange}
  mode='dialog'
>
  {
    alphabet.map((letter) => {
      return (
        <Picker.Item label={letter} value={letter} />
      );
    })
  }
</Picker>

I can work around this by adding my default value to my alphabet array, but obviously that isn't a great solution.

Or I can do:

{
  [<Picker.Item label="Please select" value='none' />].concat(
  alphabet.map((letter) => {
    return (
      <Picker.Item label={letter} value={letter} />
    );
  }))
}

but that seems like even more of a hack.

Any suggestions?

danielweinmann commented 6 years ago

Hey, @dave-irvine!

Last weekend I got tired of problems like the one you described here and created react-native-controlled-picker.

It is not the exact same solution, but it is the only 100% controlled and declarative picker I've found for RN so far :)

Can you check if it solves your problem? I intend to deprecate react-native-picker-dropdown in favor of react-native-controlled-picker.

dave-irvine commented 6 years ago

Hi @danielweinmann, thanks for getting back to me and the advice.

I'll give your other component a try, I'm sure it will solve the issue, but I will admit that I skipped over it originally because I'm not a big fan of the "controlled" pattern, i.e, having to pass the data to the component and not the children.

On the other hand, if what you've got solves the problem then there is probably no good reason for me not to use it!

danielweinmann commented 6 years ago

I see 2 separate patterns:

  1. The controlled pattern, where the component has no state and we control it via props.
  2. The data pattern, where we define the picker items via an array of objects prop.

I'm a huge fan of number 1 but have no strong opinion about number 2. The only reason I used the second pattern is that I use a FlatList and it receives a data prop.

I'm going to leave this issue open just in case you or anyone else want to solve it on react-native-dropdown-picker.

clintLandrum commented 6 years ago

@danielweinmann Did you ditch the usage of ActionSheet in react-native-controlled-picker due to conflicts in the pattern or for more control over UI or something different altogether? In regards to deprecating this module, it seems this could work better in Redux Forms and may still have it's place?

danielweinmann commented 6 years ago

@clintLandrum, I think I ditched it because I couldn't programmatically close the ActionSheet, and I needed to do so in order to make the dropdown work with react-native-stateless-form.

But I'm not advocating for deprecating this module, I'm just not using it anymore :) If anyone wants to maintain it, I'll gladly welcome a new maintainer :)