Unform

React Select

React Select is the coolest ReactJS custom <select> library.

If you're not using it, we recommend using it instead of using simple <select> elements as it's highly customizable and provides an incredible API as we'll se below.

⚠️ All examples below are using TypeScript, if you're not using it you can simply remove all type definitions as the React.FC<Props> from component definition.

Simple select

A simple replacer for default HTML <select> element :)

1import React, { useRef, useEffect } from 'react';
2import ReactSelect, {
3 OptionTypeBase,
4 Props as SelectProps,
5} from 'react-select';
6import { useField } from '@unform/core';
7
8interface Props extends SelectProps<OptionTypeBase> {
9 name: string;
10}
11
12const Select: React.FC<Props> = ({ name, ...rest }) => {
13 const selectRef = useRef(null);
14 const { fieldName, defaultValue, registerField, error } = useField(name);
15
16 useEffect(() => {
17 registerField({
18 name: fieldName,
19 ref: selectRef.current,
20 getValue: (ref: any) => {
21 if (rest.isMulti) {
22 if (!ref.state.value) {
23 return [];
24 }
25 return ref.state.value.map((option: OptionTypeBase) => option.value);
26 }
27 if (!ref.state.value) {
28 return '';
29 }
30 return ref.state.value.value;
31 },
32 });
33 }, [fieldName, registerField, rest.isMulti]);
34
35 return (
36 <ReactSelect
37 defaultValue={defaultValue}
38 ref={selectRef}
39 classNamePrefix="react-select"
40 {...rest}
41 />
42 );
43};
44
45export default Select;

Creatable

User can choose between default options or create new ones.

1import React, { useRef, useEffect } from 'react';
2import { OptionTypeBase } from 'react-select';
3import Select, { Props as CreatableProps } from 'react-select/creatable';
4import { useField } from '@unform/core';
5
6interface Props extends CreatableProps<OptionTypeBase> {
7 name: string;
8}
9
10const CreatableSelect: React.FC<Props> = ({ name, ...rest }) => {
11 const selectRef = useRef(null);
12 const { fieldName, defaultValue, registerField, error } = useField(name);
13
14 useEffect(() => {
15 registerField({
16 name: fieldName,
17 ref: selectRef.current,
18 getValue: (ref: any) => {
19 if (rest.isMulti) {
20 if (!ref.state.value) {
21 return [];
22 }
23 return ref.state.value.map((option: OptionTypeBase) => option.value);
24 }
25 if (!ref.state.value) {
26 return '';
27 }
28 return ref.state.value.value;
29 },
30 });
31 }, [fieldName, registerField, rest.isMulti]);
32
33 return (
34 <Select
35 defaultValue={defaultValue}
36 ref={selectRef}
37 classNamePrefix="react-select"
38 {...rest}
39 />
40 );
41};
42
43export default CreatableSelect;

Async

Long lists of options? No problem! Use Async Select to make an asynchronous call to an API everytime user type something in the search box.

1import React, { useRef, useEffect } from 'react';
2import { OptionTypeBase } from 'react-select';
3import Select, { Props as AsyncProps } from 'react-select/async';
4import { useField } from '@unform/core';
5
6interface Props extends AsyncProps<OptionTypeBase> {
7 name: string;
8}
9
10const AsyncSelect: React.FC<Props> = ({ name, ...rest }) => {
11 const selectRef = useRef(null);
12 const { fieldName, defaultValue, registerField, error } = useField(name);
13
14 useEffect(() => {
15 registerField({
16 name: fieldName,
17 ref: selectRef.current,
18 getValue: (ref: any) => {
19 if (rest.isMulti) {
20 if (!ref.select.state.value) {
21 return [];
22 }
23
24 return ref.select.state.value.map(
25 (option: OptionTypeBase) => option.value,
26 );
27 }
28 if (!ref.select.state.value) {
29 return '';
30 }
31
32 return ref.select.state.value.value;
33 },
34 });
35 }, [fieldName, registerField, rest.isMulti]);
36
37 return (
38 <Select
39 cacheOptions
40 defaultValue={defaultValue}
41 ref={selectRef}
42 classNamePrefix="react-select"
43 {...rest}
44 />
45 );
46};
47
48export default AsyncSelect;
Edit this page on GitHub