Clue Mediator

How to validate react-select dropdown in React

📅February 10, 2022

You may need to validate the react-select dropdown when you are dealing with a react-select dropdown in React. Just as we have created a common component for the input field in the previous article, here we will create a component for the dropdown in React.

Checkout more articles on ReactJS

Demo Application

Output - How to validate react-select dropdown in React - Clue Mediator

Output - How to validate react-select dropdown in React - Clue Mediator

Steps to validate react-select dropdown in React

  1. Create a common Select component
  2. Create a form using the Select component
  3. Output

1. Create a common Select component

Let’s create a reusable dropdown component using react-select where we will pass all required fields.

Recommended: How to get selected by only value in react-select

Same as the Input field, we have to go through a few more props to handle the validation such as `isReq`, `errorMsg`, `onValidateFunc`.

Select.js

import React, { memo } from 'react';
import PropTypes from 'prop-types';
import ReactSelect from "react-select";

const changeHandler = (e, props) => {
  let value = null;
  if (e) value = e.value;
  props.onChangeFunc(value, props.name, e);

  if (!props.onValidateFunc) return;

  let msg = null;
  if (!value && props.isReq) {
    msg = `Please select ${props.title}.`;
  }

  props.onValidateFunc(msg, props.name);
}

const Select = props => {

  const inputProps = {
    name: props.name,
    placeholder: props.placeholder || `Select ${props.title}`,
    className: props.className,
    isClearable: props.isClearable,
    value: props.options.find(x => x.value === props.value),
    options: props.options
  }

  return (
    <div class={props.outerClassName}>
      <label class="form-label">{props.title}</label>
      <reactselect {...inputprops}="" onchange="{e" ==""> changeHandler(e, props)}
      />
      {props.errorMsg && <span class="text-danger">{props.errorMsg === true ? `Please select ${props.title}.` : props.errorMsg}</span>}
    </reactselect></div>
  )
}

Select.defaultProps = {
  name: '',
  title: '',
  placeholder: '',
  className: '',
  outerClassName: 'mb-2',
  isClearable: true,
  value: '',
  options: [],
  onChangeFunc: () => { },
  isReq: null,
  onValidateFunc: () => { }
}

Select.propTypes = {
  name: PropTypes.string,
  title: PropTypes.string,
  placeholder: PropTypes.string,
  className: PropTypes.string,
  outerClassName: PropTypes.string,
  isClearable: PropTypes.bool,
  value: PropTypes.any,
  options: PropTypes.array,
  onChangeFunc: PropTypes.func,
  isReq: PropTypes.bool,
  errorMsg: PropTypes.any,
  onValidateFunc: PropTypes.func
}

export default memo(Select);

2. Create a form using the Select component

Now it’s time to use the Select component in the main component. First of all, we have to define two different state variables called `form` and `error`.

In the error state, we have defined the object for each property. The error object contains the following attributes.

  • `isReq` – For require validation
  • `errorMsg` – To render the error message on the screen
  • `onValidateFunc` – Function to handle the validation
const [form, setForm] = useState({
  country: null,
  lang: null
});

const onValidate = (value, name) => {
  setError(prev => ({
    ...prev,
    [name]: { ...prev[name], errorMsg: value }
  }));
}

const [error, setError] = useState({
  country: {
    isReq: true,
    errorMsg: '',
    onValidateFunc: onValidate
  },
  lang: {
    isReq: true,
    errorMsg: '',
    onValidateFunc: onValidate
  }
});

const onHandleChange = useCallback((value, name) => {
  setForm(prev => ({
    ...prev,
    [name]: value
  }));
}, []);

Use the following HTML to render the form in React component.

<div class="app">
  <div class="mb-3"><strong>Validate react-select dropdown in React - <a href="https://www.cluemediator.com" target="_blank" rel="noreferrer noopener">Clue Mediator</a></strong></div>
  <div class="form">
    <select name="country" title="Country" value={form.country} options={countryList} onchangefunc={onHandleChange} {...error.country}="">
    </select>
    <button class="btn btn-primary btn-sm mt-2" onclick={handleSubmit}>
      Submit
    </button>
  </div>
</div>

Let’s combine all code together and see how it looks.

App.js

import React, { useState, useCallback } from 'react';
import Select from './Select';

const countryList = [
  { value: "india", label: "India" },
  { value: "us", label: "US" },
  { value: "australia", label: "Australia" }
];
const languageList = [
  { value: "english", label: "English" },
  { value: "hindi", label: "Hindi" },
  { value: "spanish", label: "Spanish" },
  { value: "arabic", label: "Arabic" }
];

function App() {

  const [form, setForm] = useState({
    country: null,
    lang: null
  });

  const onValidate = (value, name) => {
    setError(prev => ({
      ...prev,
      [name]: { ...prev[name], errorMsg: value }
    }));
  }

  const [error, setError] = useState({
    country: {
      isReq: true,
      errorMsg: '',
      onValidateFunc: onValidate
    },
    lang: {
      isReq: true,
      errorMsg: '',
      onValidateFunc: onValidate
    }
  });

  const onHandleChange = useCallback((value, name) => {
    setForm(prev => ({
      ...prev,
      [name]: value
    }));
  }, []);

  const validateForm = () => {
    let isInvalid = false;
    Object.keys(error).forEach(x => {
      const errObj = error[x];
      if (errObj.errorMsg) {
        isInvalid = true;
      } else if (errObj.isReq && !form[x]) {
        isInvalid = true;
        onValidate(true, x);
      }
    });
    return !isInvalid;
  }

  const handleSubmit = () => {
    const isValid = validateForm();
    if (!isValid) {
      console.error('Invalid Form!');
      return false;
    }

    console.log('Data:', form);
  }

  return (
    <div class="app">
      <div class="mb-3"><strong>Validate react-select dropdown in React - <a href="https://www.cluemediator.com" target="_blank" rel="noreferrer noopener">Clue Mediator</a></strong></div>
      <div class="form">
        <select name="country" title="Country" value={form.country} options={countryList} onchangefunc={onHandleChange} {...error.country}="">
        </select>
        <button class="btn btn-primary btn-sm mt-2" onclick={handleSubmit}>
          Submit
        </button>
      </div>
    </div>
  );
}

export default App;

3. Output

Run the application and check the output in the browser.

I hope you find this article helpful.
Thank you for reading. Happy Coding..!! 🙂

Demo & Source Code

GitHub Repository StackBlitz Project