picker icon indicating copy to clipboard operation
picker copied to clipboard

How do I make a wrapper component to style a picker item in react-native-picker?

Open mtorpvret opened this issue 5 years ago • 4 comments

Question

Hi, I'm using react-native-community/picker v1.6.1, and I'm trying to make a pre-styled picker item to avoid having the color property on each item. Below is a showcase App.js. The red picker works as expected but the yellow one renders in black instead of yellow and I don't understand why. The code is tested in an iOS emulator with a freshly generated React Native app version 0.62.2 where I've installed the picker component.

import React, {useState} from 'react';
import {SafeAreaView} from 'react-native';
import {Picker} from '@react-native-community/picker';

const YellowPickerItem = props => {
  return <Picker.Item {...props} color={'yellow'} />;
};

const App = () => {
  const [redValue, setRedValue] = useState(2);
  const [yellowValue, setYellowValue] = useState(3);

  return (
    <>
      <SafeAreaView style={{flex: 1}} backgroundColor={'gray'}>
        <Picker selectedValue={redValue} onValueChange={setRedValue}>
          <Picker.Item label={'Red 1'} value={1} key={1} color={'red'} />
          <Picker.Item label={'Red 2'} value={2} key={2} color={'red'} />
          <Picker.Item label={'Red 3'} value={3} key={3} color={'red'} />
          <Picker.Item label={'Red 4'} value={4} key={4} color={'red'} />
        </Picker>
        <Picker selectedValue={yellowValue} onValueChange={setYellowValue}>
          <YellowPickerItem label={'Yellow 1'} value={1} key={1} />
          <YellowPickerItem label={'Yellow 2'} value={2} key={2} />
          <YellowPickerItem label={'Yellow 3'} value={3} key={3} />
          <YellowPickerItem label={'Yellow 4'} value={4} key={4} />
        </Picker>
      </SafeAreaView>
    </>
  );
};

export default App;

The strangest thing is that the code runs just as well if I change the YellowPickerItem component implementation to:

const YellowPickerItem = props => {
  return <SafeAreaView />;
};

I've asked this question on StackOverflow but I didn't get an answer, and I think it has something to do with this package implementation because I can get it to work with other components. It feels like I'm missing something basic about react components here, so grateful for a nudge in the right direction.

Thanks, Markus

Same question on StackOverflow: https://stackoverflow.com/questions/62247791/how-do-i-make-a-wrapper-component-to-style-a-picker-item-in-react-native-picker

mtorpvret avatar Jun 20 '20 06:06 mtorpvret

Try using the itemStyle prop on Picker container instead of targeting the Picker.Item props.

karloluis avatar Jun 30 '20 14:06 karloluis

Thanks @karloluis. I tried that now but the refresh doesn't work with that solution. I've set it up so that the color changes when I switch between dark and light mode, but the color doesn't update until the picker is scrolled if it is set on the itemStyle, but it updates directly if it is set on the Picker.Item.

It's not a big problem but I would like to understand why it doesn't work.

mtorpvret avatar Jul 02 '20 18:07 mtorpvret

That I wouldn't know. I just stumbled on your issue dealing with my own and thought I could give you some direction. Glad you found a way to solve it.

karloluis avatar Jul 27 '20 17:07 karloluis

Thanks @karloluis. I tried that now but the refresh doesn't work with that solution. I've set it up so that the color changes when I switch between dark and light mode, but the color doesn't update until the picker is scrolled if it is set on the itemStyle, but it updates directly if it is set on the Picker.Item.

It's not a big problem but I would like to understand why it doesn't work.

For anybody that comes across this issue.

Essentially, each Picker class's static Item property acts as an interface for each item. https://github.com/react-native-picker/picker/blob/master/js/PickerIOS.ios.js#L66-L68

In reality, as long as the child component has the value and label props, the Picker class will extract those values from its children and create the items internally.

You can see the children's props extracted in this code block https://github.com/react-native-picker/picker/blob/master/js/PickerIOS.ios.js#L80-L95

marcobeltempo avatar Aug 10 '22 22:08 marcobeltempo