react-native-picker-select: Placeholder does not seem to update even if objects are different

YOU MUST FILL OUT THE ENTIRE BUG REPORT

Describe the bug
I seem to be having issues with updating the placeholder after the component is mounted.

To Reproduce
Steps to reproduce the behavior:

  1. Have a managed loading state
  2. Set input to be loading
  3. Have a ternary to switch between placeholders
  4. See error

Expected behavior
The placeholder should update to the loading placeholder and back to the given placeholder

Smartphone (please complete the following information):

  • Device: iPad Mini
  • OS: iOS 12.2
  • react-native-picker-select version: ^6.1.0
  • react-native version: https://github.com/expo/react-native/archive/sdk-32.0.0.tar.gz
  • react version: 16.5.0

Reproduction and/or code sample

Investigation:
export default class RNPickerSelect extends PureComponent {
    // <snip>

    static getDerivedStateFromProps(nextProps, prevState) {
        // <snip>

        // update selectedItem if value prop is defined and differs from currently selected item
        const { selectedItem, idx } = RNPickerSelect.getSelectedItem({
            items,
            key: nextProps.itemKey,
            value: nextProps.value,
        });

        const selectedItemChanged =
            !isEqual(nextProps.value, undefined) && !isEqual(prevState.selectedItem, selectedItem);

        console.log(selectedItem, selectedItemChanged) // <-- Logging here

        if (itemsChanged || selectedItemChanged) {
            if (selectedItemChanged) {
                nextProps.onValueChange(selectedItem.value, idx);
            }

            return {
                ...(itemsChanged ? { items } : {}),
                ...(selectedItemChanged ? { selectedItem } : {}),
            };
        }

        return null;
    }

    // <snip>
}
Output:
Object {
  "color": "#9EA0A4",
  "label": "Select an item...",
  "value": null,
} false
Object {
  "label": "Loading...",
  "value": null,
} false
JSX:
<Select
    {...props}
    placeholder={(
        this.isLoading(name)
            ? {
                label: 'Loading...',
                value: null,
            }
            : null
    )}
    disabled={disabled}
    value={this.getValue(name)}
    items={options}
    style={{
        inputIOS: newStyle,
        inputAndroid: newStyle,
    }}
    onValueChange={text => call([this.onChange, onChange], { field, text })}
/>

About this issue

  • Original URL
  • State: closed
  • Created 5 years ago
  • Comments: 16

Most upvoted comments

Set the placeholder like this

placeholder={
{ label: 'Select Gender', value: null, color: '#909090', }
}

It works for me.

Same bug here When i reset the select it still remember the old value:

<RNPickerSelect
     key="csp"
     onValueChange={(value): void => SetSalePointsFilter({ key: 'csp', value })}
     Icon={(): React.ReactNode => <Unicons name="angle-down" size={22} />}
     useNativeAndroidPickerStyle={false}
     placeholder={{
          label: 'CSP',
          value: null,
          ...styles.placeholderColor,
      }}
      value={listing.filters.csp}
      style={styles.select}
      items={items.csp}
 />

Ok, it works for me. To reset the select, set the component value to null and the value of placeholder also null

<RNPickerSelect
     key="csp"
     onValueChange={(value): void => SetSalePointsFilter({ key: 'csp', value: value || null })}
     Icon={(): React.ReactNode => <Unicons name="angle-down" size={22} />}
     useNativeAndroidPickerStyle={false}
     placeholder={{
          label: 'CSP',
          value: null,
          ...styles.placeholderColor,
      }}
      value={listing.filters.csp}
      style={styles.select}
      items={items.csp}
 />

The placeholder prop expects an empty object or an object in the proper format. You’re passing in null instead - not sure how that’s going to react.