AI SYNTHESIZED • 150 SHEETS
v1.0.0

🌈 react-select Cheatsheet Completo 🌈

react-select es un componente select totalmente personalizable y extensible para React. Proporciona funcionalidades avanzadas como búsqueda, selecciones múltiples, carga asíncrona de opciones, creación de nuevas opciones y una estilización flexible, todo ello con un enfoque en la accesibilidad.


1. 🌟 Conceptos Clave

  • Componente Controlado: Por defecto, el valor de react-select se controla a través de la prop value y se actualiza a través de la prop onChange, lo que lo hace predecible y fácil de integrar con el estado de React.
  • Formato de Opciones: react-select espera que las opciones sean objetos con propiedades value (identificador único) y label (texto a mostrar).
    • Ejemplo: { value: 'apple', label: 'Manzana' }
  • Estilización Flexible: Permite una personalización profunda a través de la prop styles (CSS-in-JS), className, o la inyección de componentes personalizados.
  • Accesibilidad: Construido con un enfoque en la accesibilidad, siguiendo las pautas de WAI-ARIA.

2. 🛠 Configuración Inicial

  1. Instalación:
    npm install react-select
    # o
    yarn add react-select
  2. Importación Básica:
    import Select from 'react-select';
    ```    *   Para funcionalidades avanzadas como Async o Creatable, se importan componentes específicos del mismo paquete.
    

3. 🚀 Uso Básico

3.1. Selector Estándar (Single Select)

import React, { useState } from 'react';
import Select from 'react-select';

const fruitOptions = [
  { value: 'apple', label: 'Manzana' },
  { value: 'banana', label: 'Plátano' },
  { value: 'orange', label: 'Naranja' },
];

function SingleSelectExample() {
  const [selectedFruit, setSelectedFruit] = useState(null); // El estado guarda el objeto completo de la opción

  const handleChange = (selectedOption) => {
    setSelectedFruit(selectedOption);
    console.log(`Opción seleccionada:`, selectedOption);
  };

  return (
    <div>
      <h3>Selector de Frutas</h3>
      <Select
        options={fruitOptions}
        onChange={handleChange}
        value={selectedFruit} // El valor del Select es el objeto de la opción
        placeholder="Selecciona una fruta..."
        isClearable // Permite borrar la selección
        isSearchable // Habilita la búsqueda
      />
      {selectedFruit && <p>Has seleccionado: {selectedFruit.label}</p>}
    </div>
  );
}

export default SingleSelectExample;

3.2. Selector Múltiple (Multi Select)

Simplemente añade la prop isMulti. onChange recibirá un array de objetos de opción.

import React, { useState } from 'react';
import Select from 'react-select';

const techOptions = [
  { value: '[react](/web/frontend/general/react/react "¡Excelente! React es la biblioteca de JavaScript más popular para construir interfaces de usuario.")', label: 'React' },
  { value: 'vue', label: 'Vue.js' },
  { value: '[angular](/web/frontend/framework/angular "Angular es un framework de desarrollo de aplicaciones web de código abierto, desarrollado por Google, para construir aplicaciones de una sola página (SPA) y aplicaciones móviles de alto rendimiento.")', label: 'Angular' },
  { value: 'node', label: 'Node.js' },
  { value: '[python](/python/python "Python es un lenguaje de programación de alto nivel, interpretado, interactivo y orientado a objetos.")', label: 'Python' },
];

function MultiSelectExample() {
  const [selectedTechs, setSelectedTechs] = useState([]); // El estado guarda un array de objetos de opción

  const handleChange = (selectedOptions) =&gt; {
    setSelectedTechs(selectedOptions || []); // selectedOptions puede ser null al borrar todo
    console.log(`Opciones seleccionadas:`, selectedOptions);
  };

  return (
    <div>
      <h3>Selector de Tecnologías</h3>
      <Select
        isMulti // ¡Esta prop lo convierte en multi-select!
        options={techOptions}
        onChange={handleChange}
        value={selectedTechs} // El valor es un array de objetos de opción
        placeholder="Selecciona tecnologías..."
        closeMenuOnSelect={false} // Mantener el menú abierto después de seleccionar en multi
      />
      {selectedTechs.length > 0 && (
        <p>Has seleccionado: {selectedTechs.map(tech =&gt; tech.label).join(', ')}</p>
      )}
    </div>
  );
}

exportquire MultipleSelectExample;

4. ⚙️ Props Comunes

Select es muy configurable a través de sus props.

  • options: Array<object> - Array de objetos de opciones { value: string|number, label: string }.
  • value: object | Array<object> | null - El objeto(s) de opción seleccionado(s). Controlado.
  • onChange: (newValue: any, actionMeta: ActionMeta) =&gt; void - Función que se llama cuando el valor cambia. newValue es el objeto(s) de opción seleccionado(s).
  • isMulti: boolean - true para selección múltiple.
  • isClearable: boolean - true para mostrar un botón de “limpiar”.
  • isDisabled: boolean - true para deshabilitar el selector.
  • isLoading: boolean - true para mostrar un indicador de carga.
  • isSearchable: boolean - true para habilitar la funcionalidad de búsqueda.
  • placeholder: string - Texto que se muestra cuando no hay nada seleccionado.
  • defaultValue: object | Array<object> - El valor inicial (para componente no controlado). No usar junto con value.
  • menuIsOpen: boolean - Controla si el menú desplegable está abierto o cerrado.
  • name: string - El nombre del input (útil para formularios).
  • id: string - El ID del input.
  • className: string - Clase CSS para el contenedor principal.
  • classNamePrefix: string - Prefijo para las clases generadas internamente por react-select (ej. react-select-control).
  • components: object - Permite reemplazar componentes internos de react-select (ej. Control, Option, IndicatorSeparator).
  • formatOptionLabel: (option, { context }) =&gt; ReactNode - Función para personalizar el renderizado de cada opción en el menú.
  • noOptionsMessage: (obj: { inputValue: string }) =&gt; ReactNode - Mensaje que se muestra cuando no hay opciones disponibles.
  • loadingMessage: () =&gt; ReactNode - Mensaje que se muestra cuando isLoading es true.
  • filterOption: (option, rawInput) =&gt; boolean - Función para personalizar la lógica de filtrado de la búsqueda.
  • getOptionValue: (option) =&gt; string - Función para extraer el valor único de una opción (por defecto option.value).
  • getOptionLabel: (option) =&gt; string - Función para extraer la etiqueta a mostrar de una opción (por defecto option.label).

5. 🚀 Funcionalidades Avanzadas

5.1. Selector Asíncrono (AsyncSelect)

Para cargar opciones desde una API o una fuente de datos remota.

import React, { useState } from 'react';
import AsyncSelect from 'react-select/async'; // Importa AsyncSelect

const loadUsers = async (inputValue) =&gt; {
  // Simula una [API](/conocimiento/api "Una API (Application Programming Interface) es un conjunto de reglas, protocolos y herramientas que permite que diferentes aplicaciones de software se comuniquen entre sí.") call
  const response = await new Promise(resolve =&gt; setTimeout(() =&gt; {
    const users = [
      { id: 1, name: 'Alice' },
      { id: 2, name: 'Bob' },
      { id: 3, name: 'Charlie' },
    ];
    resolve(users.filter(user =&gt; user.name.toLowerCase().includes(inputValue.toLowerCase())));
  }, 500));

  return response.map(user =&gt; ({ value: user.id, label: user.name }));
};

function AsyncSelectExample() {
  const [selectedUser, setSelectedUser] = useState(null);

  return (
    <div>
      <h3>Buscador Asíncrono de Usuarios</h3>
      <AsyncSelect
        cacheOptions // Cachea las opciones cargadas
        loadOptions={loadUsers} // Función que carga las opciones
        defaultOptions // Carga las opciones por defecto al montar (si no quieres cargar solo al escribir)
        onChange={setSelectedUser}
        value={selectedUser}
        placeholder="Escribe para buscar usuarios..."
      />
    </div>
  );
}

export default AsyncSelectExample;

5.2. Selector “Creatable” (CreatableSelect)

Permite al usuario seleccionar una opción existente o crear una nueva.

import React, { useState } from 'react';
import CreatableSelect from 'react-select/creatable'; // Importa CreatableSelect

const colorOptions = [
  { value: 'red', label: 'Rojo' },
  { value: 'blue', label: 'Azul' },
  { value: 'green', label: 'Verde' },
];

function CreatableSelectExample() {
  const [selectedColor, setSelectedColor] = useState(null);

  const handleCreate = (inputValue) =&gt; {
    // Lógica para añadir la nueva opción a tu fuente de datos
    console.log(`Creando nueva opción: ${inputValue}`);
    const newOption = { value: inputValue.toLowerCase(), label: inputValue };
    // Idealmente, aquí también actualizarías tu lista de 'options'
    setSelectedColor(newOption); // Selecciona la nueva opción creada
  };

  return (
    <div>
      <h3>Selector de Colores (Creatable)</h3>
      <CreatableSelect
        isClearable
        options={colorOptions}
        onChange={setSelectedColor}
        onCreateOption={handleCreate} // Función para crear nueva opción
        value={selectedColor}
        placeholder="Selecciona o crea un color..."
        formatCreateLabel={(inputValue) =&gt; `Crear "${inputValue}"`} // Personaliza el texto de creación
      />
    </div>
  );
}

export default CreatableSelectExample;

5.3. Opciones Agrupadas

const groupedOptions = [
  {
    label: 'Frutas',
    options: [
      { value: 'apple', label: 'Manzana' },
      { value: 'banana', label: 'Plátano' },
    ],
  },
  {
    label: 'Vegetales',
    options: [
      { value: 'carrot', label: 'Zanahoria' },
      { value: 'brocoli', label: 'Brócoli' },
    ],
  },
];

// Uso: <Select options={groupedOptions} ... />

6. 💅 Estilización

react-select es altamente estilizable.

6.1. Usando la Prop styles (CSS-in-JS)

Permite sobrescribir los estilos de los componentes internos.

const customStyles = {
  control: (baseStyles, [state](/arquitectura/design_patterns/comportamiento/state "El patrón State es un patrón de comportamiento que permite a un objeto alterar su comportamiento cuando su estado interno cambia, haciendo que parezca que el objeto cambia de clase.")) =&gt; ({ // Estilos para el contenedor principal
    ...baseStyles,
    borderColor: [state](/arquitectura/design_patterns/comportamiento/state "El patrón State es un patrón de comportamiento que permite a un objeto alterar su comportamiento cuando su estado interno cambia, haciendo que parezca que el objeto cambia de clase.").isFocused ? 'blue' : '#ccc',
    boxShadow: [state](/arquitectura/design_patterns/comportamiento/state "El patrón State es un patrón de comportamiento que permite a un objeto alterar su comportamiento cuando su estado interno cambia, haciendo que parezca que el objeto cambia de clase.").isFocused ? '0 0 0 1px blue' : 'none',
    '&:hover': {
      borderColor: 'blue',
    },
    borderRadius: '8px',
    minHeight: '40px',
  }),
  option: (baseStyles, [state](/arquitectura/design_patterns/comportamiento/state "El patrón State es un patrón de comportamiento que permite a un objeto alterar su comportamiento cuando su estado interno cambia, haciendo que parezca que el objeto cambia de clase.")) =&gt; ({ // Estilos para cada opción del menú
    ...baseStyles,
    backgroundColor: [state](/arquitectura/design_patterns/comportamiento/state "El patrón State es un patrón de comportamiento que permite a un objeto alterar su comportamiento cuando su estado interno cambia, haciendo que parezca que el objeto cambia de clase.").isFocused ? '#e0f2f7' : (state.isSelected ? '#b2e2f2' : 'white'),
    color: [state](/arquitectura/design_patterns/comportamiento/state "El patrón State es un patrón de comportamiento que permite a un objeto alterar su comportamiento cuando su estado interno cambia, haciendo que parezca que el objeto cambia de clase.").isSelected ? 'black' : 'inherit',
    cursor: 'pointer',
    '&:active': {
      backgroundColor: '#a0daed',
    },
    padding: '10px 12px',
  }),
  singleValue: (baseStyles) =&gt; ({ // Estilos para el valor seleccionado en un single select
    ...baseStyles,
    color: '#333',
    fontWeight: 'bold',
  }),
  multiValue: (baseStyles) =&gt; ({ // Estilos para cada 'tag' en un multi-select
    ...baseStyles,
    backgroundColor: '#e0e0e0',
    borderRadius: '4px',
  }),
  multiValueLabel: (baseStyles) =&gt; ({
    ...baseStyles,
    color: '#333',
  }),
  multiValueRemove: (baseStyles) =&gt; ({
    ...baseStyles,
    color: '#999',
    '&:hover': {
      backgroundColor: '#ff7878',
      color: 'white',
    },
  }),
  placeholder: (baseStyles) =&gt; ({
    ...baseStyles,
    color: '#aaa',
  }),
  menu: (baseStyles) =&gt; ({ // Estilos para el menú desplegable
    ...baseStyles,
    borderRadius: '8px',
    boxShadow: '0 4px 8px rgba(0, 0, 0, 0.15)',
    zIndex: 9999, // Asegura que el menú esté por encima de otros elementos
  }),
  indicatorSeparator: (baseStyles) =&gt; ({ // Ocultar el separador de indicadores
    ...baseStyles,
    display: 'none',
  }),
  dropdownIndicator: (baseStyles, [state](/arquitectura/design_patterns/comportamiento/state "El patrón State es un patrón de comportamiento que permite a un objeto alterar su comportamiento cuando su estado interno cambia, haciendo que parezca que el objeto cambia de clase.")) =&gt; ({ // Estilos para el icono de flecha
    ...baseStyles,
    color: [state](/arquitectura/design_patterns/comportamiento/state "El patrón State es un patrón de comportamiento que permite a un objeto alterar su comportamiento cuando su estado interno cambia, haciendo que parezca que el objeto cambia de clase.").isFocused ? 'blue' : '#ccc',
    transition: 'transform 0.2s ease-in-out',
    transform: state.menuIsOpen ? 'rotate(180deg)' : null,
  }),
};

// Uso: <Select styles={customStyles} ... />

6.2. Usando className y CSS (o Módulos CSS)

Aplica tus propias clases CSS a la envoltura principal.

// MySelect.module.css
.my-select-container .[react](/web/frontend/general/react/react "¡Excelente! React es la biblioteca de JavaScript más popular para construir interfaces de usuario.")-select__control {
  border: 2px solid purple;
  /* ... otros estilos */
}
.my-select-container .[react](/web/frontend/general/react/react "¡Excelente! React es la biblioteca de JavaScript más popular para construir interfaces de usuario.")-select__option--is-focused {
  background-color: lightgray;
}

// MyComponent.jsx
import styles from './MySelect.module.css';
<Select
  className={styles['my-select-container']}
  classNamePrefix="[react](/web/frontend/general/react/react "¡Excelente! React es la biblioteca de JavaScript más popular para construir interfaces de usuario.")-select" // Para que las clases internas sean react-select__control, etc.
  options={...}
  // ...
/>

7. ✍️ Integración con Formularios (ej. React Hook Form)

react-select es un componente controlado, por lo que necesita ser envuelto con el Controller de React Hook Form para su correcta integración.

import React from 'react';
import { useForm, Controller } from 'react-hook-form';
import Select from 'react-select';

const options = [
  { value: 'apple', label: 'Manzana' },
  { value: 'banana', label: 'Plátano' },
];

function FormWithReactSelect() {
  const { control, handleSubmit, formState: { errors } } = useForm({
    defaultValues: {
      fruit: null, // Valor inicial para el select
    }
  });

  const onSubmit = (data) =&gt; {
    console.log('Datos del formulario:', data);
    // data.fruit contendrá el objeto de la opción seleccionada (o null)
  };

  return (
    <form onSubmit={handleSubmit(onSubmit)}>
      <label>
        Selecciona una fruta:
        <Controller
          name="fruit" // Nombre del campo en el formulario
          control={control} // Instancia de control de [React Hook Form](/web/frontend/general/react/react-hook-form "  React Hook Form es una librería fantástica para la gestión de formularios en React, conocida por su rendimiento y facilidad de uso.")
          rules={{ required: '¡Este campo es obligatorio!' }} // Reglas de validación
          render={({ field }) =&gt; ( // 'field' contiene props { onChange, onBlur, value, name, ref }
            <Select
              {...field} // Pasa todas las props de `field` (onChange, onBlur, value, etc.)
              options={options}
              isClearable
              placeholder="Elige una fruta..."
            />
          )}
        />
        {errors.fruit && <p style={{ color: 'red' }}>{errors.fruit.message}</p>}
      </label>
      <br />
      <button type="submit">Enviar Formulario</button>
    </form>
  );
}

export default FormWithReactSelect;

8. 💡 Buenas Prácticas y Consejos

  • Usar Componente Controlado: Prefiere gestionar el estado de react-select con value y onChange en el estado de tu componente de React.
  • Estructura de Opciones (value, label): Asegúrate de que tus opciones siempre sigan la estructura { value: someUniqueId, label: 'Display Text' }. Si tus datos no tienen estas claves, usa getOptionValue y getOptionLabel para mapearlos.
  • Rendimiento en Listas Grandes: Para listas con miles de opciones, considera utilizar react-window o react-virtualized con react-select para virtualizar las opciones del menú y mejorar el rendimiento de desplazamiento.
  • Accesibilidad: Aunque react-select está diseñado pensando en la accesibilidad, asegúrate de que tus personalizaciones no la rompan. Prueba con navegación por teclado y lectores de pantalla.
  • isClearable y isSearchable: Habilita estas props por defecto para una mejor experiencia de usuario.
  • Manejo de Errores Visual: Cuando uses react-select en un formulario, asegúrate de mostrar feedback visual claro (ej. borde rojo, mensaje de error) si el campo es inválido.
  • Estrategia de Estilización: Para estilos simples, la prop styles está bien. Para temas más complejos o cuando ya usas un sistema CSS (ej. Tailwind, CSS Modules), considera usar classNamePrefix o inyectar componentes personalizados con components.
  • AsyncSelect para APIs: No intentes cargar todas las opciones de una API si son muchas; usa AsyncSelect y la prop loadOptions para cargar dinámicamente.

Este cheatsheet te proporciona una referencia completa de react-select, cubriendo sus conceptos esenciales, uso básico, funcionalidades avanzadas, estilización y las mejores prácticas para integrarlo en tus aplicaciones React.

Descarga completada