Validating React-Select Dropdown with React-Form-Hook and Yup in React(TypeScript): A Step-By-Step Guide
Introduction
React-Select is a flexible and appealing Select Input control for ReactJS. When utilizing this module, it's vital to check the data in order to avoid user abuse of the input fields. Yes, and this is where the React-Form-hook with Yup comes into play. This is one of several methods for validating React-Select Fields.
Section 1
Let's start by building our development environment using β‘οΈVite.Js.
β If you already have your project folder setup in TypeScript, you can skip to the 6th step.
yarn create vite
- Assign the project a name.
- Select the project framework(REACT).
- Select
react-ts
as the variant since we'd be working with TypesScript. - Switch to the Folder that was created by running
cd yourProjectName
in your terminal. - Run
yarn
in your terminal to install the modules required for your project to start-up. - Finally, Run the command below to install the react-hook-form module, react-select module, the Yup resolver, and also the Yup module.
yarn add react-hook-form react-select @hookform/resolvers yup
Section 2
β I will be making use of the app.tsx file in my project folder.
But before that, comment out the index.css file in your main.tsx file if you generated the project using vite.js.
- We will start by clearing the code in the app function generated by vite.js in the app.tsx file, and then Import the required functions from the installed modules.
import { useState } from 'react';
import reactLogo from './assets/react.svg';
import './App.css';
// Import Installed Modules
import { yupResolver } from '@hookform/resolvers/yup';
import * as yup from "yup";
import Select from 'react-select';
import { useForm, Controller } from "react-hook-form"
function App() {
}
export default App
- Now, we will create an interface and schema for the Select Field outside the app function:
interface SelectField {
gender: { value: string, label: string }
hobbies: { value: string, label: string }[]
}
const schema = yup.object({
gender: yup.object({
value: yup.string().required("Please select a gender"),
}),
hobbies: yup.array().required("Please select an hobby").min(1, "Please select an hobby"),
})
- In our app function, we'll extract some methods from the useForm custom hook and use the yupResolver to assign the schema we created to the useForm hook. Then, add a submit function.
function App() {
const { control, handleSubmit, formState: { errors } } = useForm<SelectField>({
resolver: yupResolver(schema)
});
// Submit function
const submitHandler = (values: SelectField) => { console.log(values) };
}
Section 3
- In order to hold and submit our chosen fields, we must first create and return a form inside the app function. The "Controller" wrapper component obtained from the react-hook-form will be used to enclose our select fields there in the form. We will be able to interact with our react-select fields more easily thanks to this wrapper component. Furthermore, we'll pass our error messages below each controller field.
return (
<form onSubmit={handleSubmit(submitHandler)}>
<Controller
name={"gender"} // for the gender field
control={control} // obtained from the useForm hook
render={({ field }) => {
return (
<Select
{...field}
options={[{ value: "M", label: "Male" }, { value: "F", label: "Female" }]}
placeholder="Select Gender"
/>
)
}}
/>
<p style={{ color: "red" }}>{errors.gender?.value?.message}</p>
<Controller
name={"hobbies"} // for the gender field
control={control} // obtained from the useForm hook
render={({ field }) => {
return (
<Select
{...field}
options={[{ value: "Cooking", label: "Cooking" }, { value: "Singing", label: "Singing" }]}
placeholder="Select your Hobbies"
/>
)
}}
/>
<p style={{ color: "red" }}>{errors.hobbies?.message}</p>
<button type="submit">Submit</button>
</form>
)
The final version of our code should look like this:
import { useState } from 'react'
import reactLogo from './assets/react.svg'
import './App.css'
// Import Installed Modules
import { yupResolver } from '@hookform/resolvers/yup';
import * as yup from "yup";
import Select from 'react-select';
import { useForm, Controller } from "react-hook-form"
interface SelectField {
gender: { value: string, label: string }
hobbies: { value: string, label: string }[]
}
const schema = yup.object({
gender: yup.object({
value: yup.string().required("Please select a gender"),
}),
hobbies: yup.array().required("Please select an hobby").min(1, "Please select an hobby"),
})
function App() {
const { control, handleSubmit, formState: { errors } } = useForm<SelectField>({
resolver: yupResolver(schema)
});
const submitHandler = (values: SelectField) => { console.log(values) }
return (
<form onSubmit={handleSubmit(submitHandler)}>
<Controller
name={"gender"} // for the gender field
control={control} // obtained from the useForm hook
render={({ field }) => {
return (
<Select
{...field}
options={[{ value: "M", label: "Male" }, { value: "F", label: "Female" }]}
placeholder="Select Gender"
/>
)
}}
/>
<p style={{ color: "red" }}>{errors.gender?.value?.message}</p>
<Controller
name={"hobbies"} // for the gender field
control={control} // obtained from the useForm hook
render={({ field }) => {
return (
<Select
isMulti
{...field}
options={[{ value: "Cooking", label: "Cooking" }, { value: "Singing", label: "Singing" }]}
placeholder="Select your Hobbies"
/>
)
}}
/>
<p style={{ color: "red" }}>{errors.hobbies?.message}</p>
<button type="submit">Submit</button>
</form>
)
}
export default App
- Start the project by running the command:
yarn dev
ornpm run dev
in your terminal.
And we are done!! Check your browser's console for the values! πππ
Subscribe to my newsletter
Read articles from Macaulay Uzu directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by