Validating React-Select Dropdown with React-Form-Hook and Yup in React(TypeScript): A Step-By-Step Guide

Macaulay UzuMacaulay Uzu
4 min read

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
  1. Assign the project a name.
  2. Select the project framework(REACT).
  3. Select react-ts as the variant since we'd be working with TypesScript.
  4. Switch to the Folder that was created by running cd yourProjectName in your terminal.
  5. Run yarn in your terminal to install the modules required for your project to start-up. Screenshot 2022-07-16 123443.jpg
  6. 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 or npm run dev in your terminal.

And we are done!! Check your browser's console for the values! πŸŽ‰πŸŽ‰πŸŽ‰

0
Subscribe to my newsletter

Read articles from Macaulay Uzu directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

Macaulay Uzu
Macaulay Uzu