react-select

repository·master·Indexed 12 days ago

https://github.com/jedwatson/react-select

A powerful, highly customizable select control for ReactJS. It features a flexible approach to data, extensible styling via emotion, and a component injection API for complete UI control. Includes specialized components like AsyncSelect, AsyncCreatableSelect, and built-in TypeScript support from v5 onwards.

Tokens
15K
Snippets
42
Records
57
Agent score
97%

What's inside react-select

  1. How controllable props work in react-select

    master

    React-select allows you to either let the component manage its own state or take control of it by providing specific props.

    Controlled Mode If you provide these props, you are responsible for managing the state:

    • value / onChange: controls the current selected value.
    • menuIsOpen / onMenuOpen / onMenuClose: controls whether the dropdown menu is open.
    • inputValue / onInputChange: controls the text in the search input.

    Uncontrolled Mode (Initial Values) If you do not provide the controlled props above, you can still set initial values using these props:

    • defaultValue: set the initial value of the control.
    • defaultMenuIsOpen: set the initial open value of the menu.
    • defaultInputValue: set the initial value of the search input.
  2. Install and use react-select

    master

    Install react-select via npm or yarn. You can then import the Select component and provide an options array to render a functional select control.

    import React, { useState } from 'react';
    import Select from 'react-select';
    
    const options = [
      { value: 'chocolate', label: 'Chocolate' },
      { value: 'strawberry', label: 'Strawberry' },
      { value: 'vanilla', label: 'Vanilla' },
    ];
    
    export default function App() {
      const [selectedOption, setSelectedOption] = useState(null);
    
      return (
        <div className="App">
          <Select
            defaultValue={selectedOption}
            onChange={setSelectedOption}
            options={options}
          />
        </div>
      );
    }
  3. Understand the onCreateOption callback

    master

    The onCreateOption prop is a specialized callback for handling the creation of new options.

    When a user selects the "create new ..." option:

    1. If onCreateOption is provided: This function is called with the current inputValue. The standard onChange event will not be triggered. This is intended for developers who want to perform an async action (like an API call to save the new item) before updating the select's state.
    2. If onCreateOption is not provided: The component uses the default getNewOptionData to create an option object and then calls the standard onChange with the action set to 'create-option' in the actionMeta object.
  4. Handle keyboard navigation in Select

    master

    The Select component has built-in keyboard support. Key behaviors include:

    • ArrowUp / ArrowDown: Navigates through options in the menu or opens the menu.
    • Enter / Space: Selects the currently focused option.
    • Escape: Closes the menu or clears the value (if isClearable and escapeClearsValue are enabled).
    • Tab: Selects the focused option if tabSelectsValue is enabled.
    • Backspace / Delete: Removes the focused value or the last value in multi-select mode (if backspaceRemovesValue is enabled).
    • Home / End / PageUp / PageDown: Navigates to the start, end, or pages of the option list.

    You can intercept or extend these behaviors by providing your own onKeyDown prop.

  5. Customize Select components

    master

    The Select component is highly composable. You can override any of its internal parts by passing custom components via the components prop. The component uses getComponents() to resolve these, which merges your custom components with the defaultComponents.

    Commonly customized components include:

    • Control
    • ValueContainer
    • Input
    • Placeholder
    • SingleValue / MultiValue
    • Menu / MenuList / Option / Group
    • DropdownIndicator / ClearIndicator / LoadingIndicator
  6. Customize Select components using the components prop

    master

    You can override the default UI of react-select by providing a components object to the Select component. This object allows you to replace specific internal parts of the select (like the Control, Menu, Option, or Indicator) with your own custom React components.

    To create a custom configuration, you can use the defaultComponents helper function. This function merges your custom components with the library's default ones, ensuring that any components you don't override continue to function as expected.

    When defining custom components, they must match the expected prop types for that specific part of the select, which are generic based on your Option type, whether the select is multi-select (IsMulti), and your Group structure.

    import Select, { defaultComponents } from 'react-select';
    
    const CustomOption = (props) => (
      <option {...props}>Custom: {props.label}</option>
    );
    
    const customComponents = defaultComponents({
      Option: CustomOption
    });
    
    function MySelect({ options }) {
      return <Select options={options} components={customComponents} />;
    }
  7. Configure custom accessibility messages with AriaLiveMessages

    master

    To customize the screen reader announcements in react-select, provide an ariaLiveMessages object to your component. This object allows you to override the default strings used for guidance, value changes, filtering, and focus events.

    Supported message functions include:

    • guidance: Conveys component state and keyboard interactivity (e.g., how to navigate the menu).
    • onChange: Conveys changes to the selected value (e.g., when an option is selected or cleared).
    • onFilter: Conveys information about filtered results during search.
    • onFocus: Conveys information about the currently focused option in the menu or value.

    Each function receives a specific props object containing the current state of the component (like isMulti, isSearchable, isDisabled, etc.) to help you construct context-aware strings.

    const customAriaLiveMessages = {
      guidance: (props: AriaGuidanceProps) => `Custom guidance: ${props.context}`,
      onChange: (props: AriaOnChangeProps<Option, boolean>) => `Selected: ${props.label}`,
      onFilter: (props: AriaOnFilterProps) => `Found ${props.resultsMessage}`,
      onFocus: (props: AriaOnFocusProps<Option, GroupBase<Option>>) => `Focused ${props.label}`
    };
    
    // Use in your Select component
    <Select ariaLiveMessages={customAriaLiveMessages} ... />
  8. Configure Creatable options in react-select

    master

    When using a creatable version of react-select, you can use the CreatableAdditionalProps to customize how new options are generated and displayed.

    Key customization options include:

    • allowCreateWhileLoading: A boolean that, if true, allows the "create new ..." option to appear even when isLoading is true. This is useful for preventing the option from flickering while async results are loading.
    • createOptionPosition: Determines if the new option appears at the 'first' or 'last' position in the list. Defaults to 'last'.
    • formatCreateLabel: A function (inputValue: string) => ReactNode used to customize the text of the creation option (e.g., Create "my text").
    • isValidNewOption: A predicate function (inputValue, value, options, accessors) => boolean that determines if the current input qualifies as a valid new option (e.g., checking that it doesn't already exist in the current options or selected values).
    • getNewOptionData: A function (inputValue: string, optionLabel: ReactNode) => Option that defines the shape of the object created when a user selects the "create" option. This object is what gets passed to onChange.
    • onCreateOption: A callback (inputValue: string) => void that is triggered when a new option is created. If this is provided, the default onChange behavior is bypassed, giving you full control over the creation lifecycle.
    // Example of customizing a creatable select
    <CreatableSelect
      allowCreateWhileLoading={true}
      createOptionPosition="first"
      formatCreateLabel={(input) => `Add new item: ${input}`}
      getNewOptionData={(input) => ({
        label: input,
        value: input.toLowerCase(),
        __isNew__: true
      }))
      isValidNewOption={(input, value, options, accessors) => {
        // Custom logic to prevent duplicates
        return input.length > 0 && !options.some(opt => accessors.getOptionValue(opt) === input);
      }}
    />
  9. Configure Menu positioning and portalling

    master

    You can control how and where the dropdown menu is rendered using these props:

    • menuPlacement: Determines where the menu appears (e.g., top or bottom).
    • menuPosition: Controls the rendering strategy. Options include 'fixed' or using a menuPortalTarget.
    • menuPortalTarget: An HTML element (e.g., document.body) where the menu should be portalled to avoid z-index or overflow issues.
    • minMenuHeight / maxMenuHeight: Constraints for the menu's height.
    • menuShouldBlockScroll: A boolean to determine if scrolling should be disabled on the body when the menu is open.
    • menuShouldScrollIntoView: A boolean to determine if the menu should scroll into view when opened.
  10. Common Props for Select

    master

    The following props are commonly used to configure the Select component:

    • autoFocus: focus the control when it mounts
    • className: apply a className to the control
    • classNamePrefix: apply classNames to inner elements with the given prefix
    • isDisabled: disable the control
    • isMulti: allow the user to select multiple values
    • isSearchable: allow the user to search for matching options
    • name: generate an HTML input with this name, containing the current value
    • onChange: subscribe to change events
    • options: specify the options the user can select from
    • placeholder: change the text displayed when no option is selected
    • noOptionsMessage: ({ inputValue: string }) => string | null - Text to display when there are no options
    • value: control the current value