Shift-left benefits for mobile app development is not just a tool problem

When you’re building mobile apps, one of the most common components you need is a picker. A picker allows you to use your system’s UI component to choose an option from a list. From choosing dates for booking flights to selecting options in a form, pickers are used everywhere.
In this tutorial, we’ll build a React Native picker and understand how it works. I’ll also demonstrate how you can use it alongside numerous examples using the library React-Native-Picker. Finally, we’ll also write some tests for our picker. Let’s get rolling!
You have likely used select menus and drop-downs on websites. A picker is the equivalent of those in a mobile app. It renders a native UI component to choose a value from a list of options.
This means that if you use a picker on an Android device, it will render Android’s UI component for the picker. Similarly, if you’re on an iOS device, you’ll see a native iOS picker on the screen.
Pickers allow you to create an intuitive way for your users to select an option. They have use cases in all kinds of applications: e-commerce, social media, hotel booking apps, etc. They’re also used in various forms. For instance, if you wish to book a flight on an app, you’ll most likely use a date picker to select dates for your journey.
Another example would be an online menu. You could have a picker that displays a list of food items a user can choose from when ordering their food.
Now that you know what pickers are, let’s go ahead and build one.
For brevity, we’ll use Expo-CLI to create our React Native application. If you’re new to Expo, you can read about how to get started with it.
Let’s create a new Expo project by running the following:
expo init rn-picker-tutorial
Choose a blank template for the project. Once the setup completes, run npm start to kickstart your Expo app.
Luckily, there’s an amazing React Native library that gives you an easy way to use pickers. Let’s install it:
expo install @react-native-picker/picker
It does all the heavy lifting for us and gives us a simple way to interact with the system UI for rendering pickers in our application. After you’ve installed the library, you may need to restart your Expo server again.
We’re done with the installation. Next, let’s start using this library in our project.
First things first, you need to import the Picker component from the library wherever you wish to use it. We’ll put most of our code inside our App.js file. So let’s import the Picker component inside our project’s App.js:
import {Picker} from '@react-native-picker/picker';
We’ll also need a state to handle the currently selected option from the picker. So let’s also import the useState hook from React.
import React,{useState} from 'react';
Next, let’s create a simple state pokemon that stores the currently selected Pokémon from the picker.
const [pokemon,setPokemon] = useState();
We’ll create a simple picker that allows us to select a Pokémon from a list of them.
Let’s now render the <Picker> component inside our App.js:
<View style={styles.container}>
<Picker
selectedValue={pokemon}
>
</Picker>
</View>
The <Picker> component takes the selectedValue prop, which indicates the default selected value for the picker. Since we want this to be dynamic, we have used our pokemon state here. But where’s the list of options this picker needs to render?
The <Picker/> component is actually a higher-order component that renders the <Picker.Item/> component to indicate each option in the picker. Let’s do that:
<View style={styles.container}>
<Picker
style={styles.pickerStyles}
selectedValue={pokemon}
onValueChange={handleValueChange}>
<Picker.Item label="Pikachu" value="pikachu" />
<Picker.Item label="Charmander" value="charmander" />
<Picker.Item label="Squirtle" value="Squirtle" />
</Picker>
</View>
Each <Picker.Item/> child component takes in a label and a value prop. The former indicates the name of the option and the latter indicates the value of that option.
Alternately, you can also render these picker items dynamically from an array.
import React,{useState} from 'react';
import { StyleSheet, View } from 'react-native';
import {Picker} from '@react-native-picker/picker';
const pokemons=['Pikachu','Charmander','Squirtle'];
export default function App() {
const [pokemon,setPokemon] = useState();
return (
<View style={styles.container}>
<Picker
selectedValue={pokemon}
onValueChange={handleValueChange}>
{
pokemons.map(pokemon=><Picker.Item key={pokemon} label={pokemon} value={pokemon}/>)
}
</Picker>
</View>
);
}
});
In the above code we cycle through each of the Pokémon present in the pokemons array and render a <Picker.Item/> component for each.
Notice that in the above code we have also added another prop onValueChange to our <Picker/> component. This prop takes in a function that is fired whenever an option is selected from the picker. We have assigned it to be the handleValueChange function. However, that function doesn’t exist now.
So let’s go ahead and create it:
const handleValueChange=(itemValue, itemIndex) =>setPokemon(itemValue)
Inside the handleValueChange function, we get the itemValue, which indicates the selected value of the picker option. We also get the itemIndex, based on the sequence of rendered picker items. Inside the above handleValueChange function, we simply set the itemValue to our pokemon state using the setPokemon function.
If you check your app now, you’ll only see a small drop-down arrow on the screen. This is because, by default, you need to set some width to your picker. Let’s use this opportunity to also style the picker.
We can style the <Picker/> component like any other React Native component. First, we need to create a styles object inside our style sheet. Let’s use the default style sheet created inside the App.js for this:
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#fff',
alignItems: 'center',
justifyContent: 'center',
},
pickerStyles:{
width:'70%',
backgroundColor:'gray',
color:'white'
}
});
Now we simply need to assign styles.pickerStyles to the style prop of our <Picker/> component:
<View style={styles.container}>
<Picker
style={styles.pickerStyles}
selectedValue={pokemon}
onValueChange={handleValueChange}>
<Picker.Item label="Pikachu" value="pikachu" />
<Picker.Item label="Charmander" value="charmander" />
<Picker.Item label="Squirtle" value="Squirtle" />
</Picker>
</View>
Now you should see a gray picker rendered on the screen as shown:
Awesome! If you open this picker, you should also be able to see the list of options. Consequently, you should be able to choose other options from the list as well.
Great! You’ve learned how to build a picker in your React Native application. Let’s explore some other features of this library and how they can be useful.
We have already seen the important props for the <Picker/> component. Next, let’s see some other props that can be useful.
You may run into use cases where you might want to disable the picker. For instance, you could want to conditionally allow the user to select an item from the picker. Or you might only want premium members of your app to select options.
For this purpose, you can use the enabled prop. You can set the enabled prop inside the <Picker/> component to false. This will disable the <Picker/> completely. You’ll no longer be able to open the list of options, select an item, or do any other kind of interaction with the <Picker/>.
<Picker
enabled={false}
...
</Picker>
The mode prop allows you to specify the UI component used to render the picker items. By default, the mode is set to a dialog. This is why, when you open the picker, you see a background overlay on the screen.
However, you can change this to render your picker items as a drop-down as well. All you need to do is set the mode prop to dropdown as shown:
<Picker
mode={'dropdown'}
...
</Picker>
If you check the picker now, you should see a drop-down menu instead as shown:
You can also use the dropdownIconColor prop to change the color of the drop-down arrow icon.
<Picker
dropdownIconColor={'red'}
...
</Picker>
You should now see a red downward arrow as shown in the picker:
You may also wish to programmatically do something when the picker is in a focus or blur state. The focus state represents the state of picker when you’ve clicked it to toggle the list of options.
When you press anywhere outside, the picker is in a blur state. We get access to these states and events of the <Picker/> component. Let’s create a simple state that represents the focus state of the picker:
const [isPickerFocused,setIsPickerFocused]=useState()
Next, create a function that toggles this state:
const handleFocus=(focus)=>setIsPickerFocused(focus);
To see this in action, let’s render this state inside our App.js right above the <Picker/> component:
<Text style={{marginBottom:200}}>Picker is {isPickerFocused ? 'focused' : 'not focused'} </Text>
Now we can call the handleFocus function using the onBlur and onFocus prop that we get access to in our <Picker/> component.
<Picker
onBlur={()=>handleFocus(false)}
onFocus={()=>handleFocus(true)}
...
</Picker>
If you now open the Picker, you should see that it’s in a focus state:
Consequently, if you now close the picker, you should see it in a blur state:
What good is your code if it can’t pass all test cases? Automation testing allows you to build robust and foolproof apps. So let’s go ahead and write a simple snapshot test for our picker.
First, we need to install a few libraries for this purpose:
npm i jest jest-expo @testing-library/react-native
At the root of our project, create an App.test.js file with the following code:
import React from 'react';
import {render} from '@testing-library/react-native'
import App from './App';
describe('<App />', () => {
it('should match snapshot', () => {
const app=render(<App />);
const picker = app.getByTestId('test-picker')
expect(picker).toMatchSnapshot()
});
});
In the above code, we first grab our app component using the render function. Then, we get the <Picker/> component using a testID prop. Finally, we call the toMatchSnapshot() method, which compares snapshots of our <Picker/> component rendered in our app.
However, we need to assign a testID prop to our <Picker/> component. Only then will we be able to get a reference to our <Picker/> component. Head back to your App.js and add the testID prop to the <Picker/> component as shown:
<Picker
testID={'test-picker'}
...
/>
Great! You’re good to go now. Let’s run our snapshot test by running the following:
npm run test
And voilà! We see that our <Picker/> component has passed the snapshot test with flying colors!
But there’s a lot more you can do than snapshot testing. You could write more unit or end-to-end tests to make your picker component more foolproof. However, testing sometimes becomes a different ball game altogether, and most developers struggle to write great tests that make their apps stable.
In these situations, no-code testing tools are a lifesaver. For this, check out Waldo, which allows you to easily write and record automated tests in your browser without writing a single line of code!
Now that you’ve learned how to create and use pickers in your React Native application, a great exercise would be to use that knowledge to build something awesome! For instance, you can build a form in your app that allows users to choose an option via a picker. Or you could style these pickers in a way that fits the design system of your app. We explored a bunch of cool props that the library offers, but there’s more to it that might be useful for you.
This post was written by Siddhant Varma. Siddhant is a full stack JavaScript developer with expertise in frontend engineering. He’s worked with scaling multiple startups in India and has experience building products in the Ed-Tech and healthcare industries. Siddhant has a passion for teaching and a knack for writing. He’s also taught programming to many graduates, helping them become better future developers.