Selaimen sisäänrakennettu <select>-komponentti mahdollistaa valintalistan renderöimisen vaihtoehtoineen.

<select>
<option value="someOption">Jokin vaihtoehto</option>
<option value="otherOption">Toinen vaihtoehto</option>
</select>

Viite

<select>

Näyttääksesi valintalistan, renderöi selaimen sisäänrakennettu <select>-komponentti.

<select>
<option value="someOption">Jokin vaihtoehto</option>
<option value="otherOption">Toinen vaihtoehto</option>
</select>

Näe lisää esimerkkejä alla.

Propsit

<select> tukee kaikkia yleisten elementtien propseja.

Voit tehdä valintalistan kontrolloiduksi antamalla value-propsin:

  • value: Merkkijono (tai merkkijonojen taulukko multiple={true}). Ohjaa, mikä vaihtoehto on valittuna. Jokainen merkkijonon arvo vastaa jonkin <option>-komponentin value-arvoa, joka on upotettu <select>-komponenttiin.

Kun välität value:n, sinun täytyy myös välittää onChange-käsittelijäfunktio, joka päivittää välitetyn arvon.

Jos <select> on kontrolloimaton, voit antaa defaultValue-propsin:

Nämä <select>-propsit ovat olennaisia sekä kontrolloimattomille että kontrolloiduille valintalistoille:

Rajoitukset

  • Toisin kuin HTML:ssä, <option>-komponentin selected-attribuutti ei ole tuettu. Sen sijaan, käytä <select defaultValue> kontrolloimattomille valintalistoille ja <select value> kontrolloiduille valintalistoille.
  • Jos valintalista vastaanottaa value-propsin, se käsitellään kontrolloituna.
  • Valintalista ei voi olla sekä kontrolloitu että kontrolloimaton samaan aikaan.
  • Valintalista ei voi vaihtaa kontrolloidusta kontrolloimattomaan elinkaarensa aikana.
  • Jokainen kontrolloitu valintalista tarvitsee onChange-käsittelijäfunktion, joka päivittää arvon synkronisesti.

Käyttö

Valintalistan näyttäminen vaihtoehdoilla

Renderöi <select>-komponentti, jossa on sisällä lista <option>-komponentteja näyttääksesi valintalistan. Anna jokaiselle <option>-komponentille value, joka edustaa dataa, joka lähetetään lomakkeen mukana.

export default function FruitPicker() {
  return (
    <label>
      Valitse hedelmä:
      <select name="selectedFruit">
        <option value="apple">Omena</option>
        <option value="banana">Banaani</option>
        <option value="orange">Orange</option>
      </select>
    </label>
  );
}


Otsikon tarjoaminen valintalistalle

Tyypillisesti, laitat jokaisen <select>-komponentin <label> tagin sisälle. Tämä kertoo selaimelle, että tämä otsikko on yhdistetty tähän valintalistaan. Kun käyttäjä klikkaa otsikkoa, selain kohdistaa automaattisesti valintalistan. Tämä on myös olennaista saavutettavuuden kannalta: ruudunlukija ilmoittaa otsikon kuvauksen kun käyttäjä kohdistaa valintalistan.

If you can’t nest <select> into a <label>, associate them by passing the same ID to <select id> and <label htmlFor>. To avoid conflicts between multiple instances of one component, generate such an ID with useId.

Jos et voi sijoittaaa <select>-komponenttia <label>-komponentin sisään, yhdistä ne antamalla sama ID <select id>:lle ja <label htmlFor>. Välttääksesi konflikteja useiden saman komponentin instanssien välillä, generoi tällainen ID useId-komponentilla.

import { useId } from 'react';

export default function Form() {
  const vegetableSelectId = useId();
  return (
    <>
      <label>
        Valitse hedelmä:
        <select name="selectedFruit">
          <option value="apple">Omena</option>
          <option value="banana">Banaani</option>
          <option value="orange">Appelsiini</option>
        </select>
      </label>
      <hr />
      <label htmlFor={vegetableSelectId}>
        Valitse vihannes:
      </label>
      <select id={vegetableSelectId} name="selectedVegetable">
        <option value="cucumber">Kurkku</option>
        <option value="corn">Maissi</option>
        <option value="tomato">Tomaatti</option>
      </select>
    </>
  );
}


Aluksi valitun valinnan tarjoaminen

Oletuksena, selain valitsee ensimmäisen <option>-komponentin listasta. Valitaksesi eri vaihtoehdon oletuksena, välitä sen <option>-komponentin value-arvo <select>-komponentille defaultValue-propsina.

export default function FruitPicker() {
  return (
    <label>
      Valitse hedelmä:
      <select name="selectedFruit" defaultValue="orange">
        <option value="apple">Omena</option>
        <option value="banana">Banaani</option>
        <option value="orange">Appelsiini</option>
      </select>
    </label>
  );
}

Sudenkuoppa

Toisin kuin HTML:ssä, <option>-komponentin selected-attribuutti ei ole tuettu.


Usean valinnan mahdollistaminen

Välitä multiple={true} <select>-komponentille, jotta käyttäjä voi valita useita vaihtoehtoja. Tässä tapauksessa, jos määrität myös defaultValue-propsin valitaksesi aluksi valitut vaihtoehdot, sen täytyy olla taulukko.

export default function FruitPicker() {
  return (
    <label>
      Valitse muutama hedelmä:
      <select
        name="selectedFruit"
        defaultValue={['orange', 'banana']}
        multiple={true}
      >
        <option value="apple">Omena</option>
        <option value="banana">Banaani</option>
        <option value="orange">Appelsiini</option>
      </select>
    </label>
  );
}


Valintalistan arvon lukeminen lomakkeen lähetyksessä

Lisää <form> valintalistan ympärille, jossa on <button type="submit"> sisällä. Se kutsuu <form onSubmit>-käsittelijäfunktiota. Oletuksena, selain lähettää lomakkeen datan nykyiseen URL:iin ja päivittää sivun. Voit ohittaa tämän käyttäytymisen kutsumalla e.preventDefault(). Lue lomakkeen data new FormData(e.target) avulla.

export default function EditPost() {
  function handleSubmit(e) {
    // Estä selainta lataamasta sivua uudelleen
    e.preventDefault();
    // Lue lomakkeen data
    const form = e.target;
    const formData = new FormData(form);
    // Voit välittää formData:n suoraan fetchin bodylle:
    fetch('/some-api', { method: form.method, body: formData });
    // Voit generoida siitä URL:n, kuten selain tekee oletuksena:
    console.log(new URLSearchParams(formData).toString());
    // Voit käsitellä sitä tavallisena oliona.
    const formJson = Object.fromEntries(formData.entries());
    console.log(formJson); // (!) Tämä ei sisällä usean valinnan arvoja
    // Tai voit saada nimi-arvo parien taulukon.
    console.log([...formData.entries()]);
  }

  return (
    <form method="post" onSubmit={handleSubmit}>
      <label>
        Valitse lempihedelmäsi:
        <select name="selectedFruit" defaultValue="orange">
          <option value="apple">Omena</option>
          <option value="banana">Banaani</option>
          <option value="orange">Appelsiini</option>
        </select>
      </label>
      <label>
        Valitse kaikki lempivihanneksesi:
        <select
          name="selectedVegetables"
          multiple={true}
          defaultValue={['corn', 'tomato']}
        >
          <option value="cucumber">Kurkku</option>
          <option value="corn">Maissi</option>
          <option value="tomato">Tomaatti</option>
        </select>
      </label>
      <hr />
      <button type="reset">Nollaa</button>
      <button type="submit">Lähetä</button>
    </form>
  );
}

Huomaa

Anna <select>:lle name, esimerkiksi <select name="selectedFruit" />. Määrittelemäsi name käytetään avaimena lomakkeen datassa, esimerkiksi { selectedFruit: "orange" }.

Jos käytät <select multiple={true}>, FormData jota luet lomakkeesta sisältää jokaisen valitun arvon erillisenä nimi-arvo parina. Katso tarkasti konsolin lokeja yllä olevassa esimerkissä.

Sudenkuoppa

Oletuksena, mikä tahansa <form>:n sisällä oleva <button> lähettää sen. Tämä voi olla yllättävää! Jos sinulla on oma Button React-komponentti, harkitse <button type="button"> palauttamista <button>:n sijaan. Sitten, ollaksesi eksplisiittinen, käytä <button type="submit"> painikkeisiin, joiden on tarkoitus lähettää lomake.


Valintalistan ohjaaminen tilamuuttujalla

Valintalista kuten <select /> on kontrolloimaton. Vaikka välittäisit aluksi valitun arvon kuten <select defaultValue="orange" />, JSX:si määrittelee vain aluksi valitun arvon, ei arvoa juuri nyt.

Renderöidäksesi kontrolloidun valintalistan, välitä sille value-propsi. React pakottaa valintalistan aina sisältämään välittämäsi value-arvon. Tyypillisesti, ohjaat valintalistaa määrittämällä tilamuuttujan:

function FruitPicker() {
const [selectedFruit, setSelectedFruit] = useState('orange'); // Määritä tilamuuttuja...
// ...
return (
<select
value={selectedFruit} // ...pakota valintalistan arvo vastaamaan tilamuuttujaa...
onChange={e => setSelectedFruit(e.target.value)} // ... ja päivitä tilamuuttuja muutoksissa!
>
<option value="apple">Omena</option>
<option value="banana">Banaani</option>
<option value="orange">Appelsiini</option>
</select>
);
}

Tämä on hyödyllistä, jos haluat renderöidä uudelleen osan käyttöliittymästä jokaisen valinnan jälkeen.

import { useState } from 'react';

export default function FruitPicker() {
  const [selectedFruit, setSelectedFruit] = useState('orange');
  const [selectedVegs, setSelectedVegs] = useState(['corn', 'tomato']);
  return (
    <>
      <label>
        Valitse hedelmä:
        <select
          value={selectedFruit}
          onChange={e => setSelectedFruit(e.target.value)}
        >
          <option value="apple">Omena</option>
          <option value="banana">Banaani</option>
          <option value="orange">Appelsiini</option>
        </select>
      </label>
      <hr />
      <label>
        Valitse kaikki lempivihanneksesi:
        <select
          multiple={true}
          value={selectedVegs}
          onChange={e => {
            const options = [...e.target.selectedOptions];
            const values = options.map(option => option.value);
            setSelectedVegs(values);
          }}
        >
          <option value="cucumber">Kurkku</option>
          <option value="corn">Maissi</option>
          <option value="tomato">Tomaatti</option>
        </select>
      </label>
      <hr />
      <p>Lempihedelmäsi: {selectedFruit}</p>
      <p>Lempivihanneksesi: {selectedVegs.join(', ')}</p>
    </>
  );
}

Sudenkuoppa

Jos välität value:n ilman onChange:a, vaihtoehdon valitseminen on mahdotonta. Kun ohjaat valintalistaa välittämällä sille value:n, pakotat sen aina sisältämään välittämäsi arvon. Joten jos välität tilamuuttujan value:na mutta unohdat päivittää tilamuuttujaa synkronisesti onChange-käsittelijäfunktion aikana, React palauttaa valintalistan jokaisen näppäinpainalluksen jälkeen takaisin value:n, jonka määritit.

Toisin kuin HTML:ssä, <option>-komponentin selected-attribuutti ei ole tuettu.