Implementing Dropdown Selection with React Hook Form in React Native

I was using React Hook Form in my new React Native project. Unfortunately I was not able to find any useful examples of React Hook Form’ dropdown implementation in React Native except this one. So I had to put some time figuring this out for myself.

My requirement was quite simple. I have had a small form to build including some dropdown selection lists. The very first thing I had to decide was to find a good and stable dropdown/selection package for react native. My search ended at these two packages:

react-native-picker-select

@react-native-picker/picker

Since I was building my React Native app on the top of Expo framework, the  @react-native-picker/picker was the default recommended package in Expo documentation. I decided to use it.

I installed it and then went to use it. However, I had to be disappointed since the interface UI was not good enough. The dropdown looked scattered on the page, horizontally,  like this:

It was taking too much of space around the selection element. I could not find a quick work around to control this behavior so I turned back to the first one i.e. react-native-picker-select.

To my surprise, the react-native-picker-select was built on the top of react-native-picker/picker so I was kind of Ok to use both to make my dropdown working eventually.

Here is the complete code

Include the packages:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
import RNPickerSelect from 'react-native-picker-select';
import RNPickerSelect from 'react-native-picker-select';
import RNPickerSelect from 'react-native-picker-select';
Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
import { useForm, Controller } from "react-hook-form";
import { useForm, Controller } from "react-hook-form";
import { useForm, Controller } from "react-hook-form";

Initialise the React Hook Form inside main component function:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
const { control, handleSubmit, formState: { errors } } = useForm({
defaultValues: {
sport: '',
}
});
const { control, handleSubmit, formState: { errors } } = useForm({ defaultValues: { sport: '', } });
const { control, handleSubmit, formState: { errors } } = useForm({
    defaultValues: {
        sport: '',
    }
});

Create a onSubmit function:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
const onSubmit = (data:object) => {
console.log(data)
}
const onSubmit = (data:object) => { console.log(data) }
const onSubmit = (data:object) => {
    console.log(data)
}

Render the dropdown within React Hook Form’s <Controller />

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
<Controller
control={control}
rules={{
required: true,
}}
render={({ field: { onChange, onBlur, value } }) => (
<RNPickerSelect
onValueChange={
(value) => {
console.log(value)
onChange(value)
}
}
items={[
{ label: 'Football', value: 'football' },
{ label: 'Baseball', value: 'baseball' },
{ label: 'Hockey', value: 'hockey' },
]}
onClose={(value) => {
console.log("I am closed")
}}
/>
)}
name="sport"
/>
{errors.sport && <Text className="text-red-500 mt-0.5 pl-0.5">This is required.</Text>}
<Controller control={control} rules={{ required: true, }} render={({ field: { onChange, onBlur, value } }) => ( <RNPickerSelect onValueChange={ (value) => { console.log(value) onChange(value) } } items={[ { label: 'Football', value: 'football' }, { label: 'Baseball', value: 'baseball' }, { label: 'Hockey', value: 'hockey' }, ]} onClose={(value) => { console.log("I am closed") }} /> )} name="sport" /> {errors.sport && <Text className="text-red-500 mt-0.5 pl-0.5">This is required.</Text>}
<Controller
    control={control}
    rules={{
        required: true,
    }}
    render={({ field: { onChange, onBlur, value } }) => (
        <RNPickerSelect
            onValueChange={
                (value) => {
                    console.log(value)
                    onChange(value)
                }
            }
            items={[
                { label: 'Football', value: 'football' },
                { label: 'Baseball', value: 'baseball' },
                { label: 'Hockey', value: 'hockey' },
            ]}
            onClose={(value) => {
                console.log("I am closed")
            }}
        />
    )}
    name="sport"
/>
{errors.sport && <Text className="text-red-500 mt-0.5 pl-0.5">This is required.</Text>}

Calling onChange(value) within onValueChange  does the trick for ReactHookForm:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
onValueChange={
(value) => {
console.log(value)
onChange(value)
}
}
onValueChange={ (value) => { console.log(value) onChange(value) } }
onValueChange={
    (value) => {
        console.log(value)
        onChange(value)
    }
}

Clicking Submit button would print the value in console.log

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
LOG {"sport": "football"}
LOG {"sport": "football"}
LOG  {"sport": "football"}

 

One thought on “Implementing Dropdown Selection with React Hook Form in React Native

Leave a Reply