Selaimen sisäänrakennettu <input>-komponentti mahdollistaa erilaisten lomakkeiden syöttökenttien renderöinnin.

<input />

Viite

<input>

Näyttääksesi syöttökentän, renderöi selaimen sisäänrakennettu <input>-komponentti.

<input name="myInput" />

Näe lisää esimerkkejä alla.

Propsit

<input> tukee kaikkia yleisten elementtien propseja.

Voit tehdä syöttökentästä kontrolloidun antamalla yhden näistä propseista:

  • checked: Totuusarvo. Valintaruudun tai radiopainikkeen kohdalla, kontrolloi onko se valittu.
  • value: Merkkijono. Tekstikentän kohdalla, kontrolloi sen tekstiä. (Radiopainikkeen kohdalla, määrittää sen lomakedatan.)

Kun käytät <input>-komponenttia kontrolloidun syöttökentän kanssa, sinun täytyy myös antaa onChange-käsittelijäfunktio, joka päivittää value-arvon.

Nämä <input>-propit ovat olennaisia vain kontrolloimattomille syöttökentille:

Nämä <input>-propsit ovat olennaisia sekä kontrolloimattomille että kontrolloiduille syöttökentille:

  • accept: Merkkijono. Määrittää mitä tiedostotyyppejä hyväksytään type="file"-kentällä.
  • alt: Merkkijono. Määrittää vaihtoehtoisen kuvatekstin type="image"-kentälle.
  • capture: Merkkijono. Määrittää median (mikrofoni, video, tai kamera) joka tallennetaan type="file"-kentällä.
  • autoComplete: Merkkijono. Määrittää yhden mahdollisista autocomplete-käyttäytymisistä.
  • autoFocus: Totuusarvo. Jos true, React kohdistaa elementtiin mountatessa.
  • dirname: Merkkijono. Määrittää elementin suunnan lomakkeen kentän nimen.
  • disabled: Totuusarvo. Jos true, syöttökenttä ei ole interaktiivinen ja näkyy himmennettynä.
  • form: Merkkijono. Määrittää <form> lomakkeen id :n johon tämä kenttä kuuluu. Jos jätetty pois, se on lähin ylätason lomake.
  • formAction: Merkkijono. Ylikirjoittaa ylätason <form action>-arvon type="submit" ja type="image"-kentille.
  • formEnctype: Merkkijono. Ylikirjoittaa ylätason <form enctype>-arvon type="submit" ja type="image"-kentille.
  • formMethod: Merkkijono. Ylikirjoittaa ylätason <form method>-arvon type="submit" ja type="image"-kentille.
  • formNoValidate: Merkkijono. Ylikirjoittaa ylätason <form noValidate>-arvon type="submit" ja type="image"-kentille.
  • formTarget: Merkkijono. Ylikirjoittaa ylätason <form target>-arvon type="submit" ja type="image"-kentille.
  • height: Merkkijono. Määrittää kuvan korkeuden type="image"-kentälle.
  • list: Merkkijono. Määrittää <datalist>-elementin id:n, jossa on autocomplete-vaihtoehdot.
  • max: Numero. Määrittää numeeristen ja päivämääräkenttien maksimiarvon.
  • maxLength: Numero. Määrittää tekstin ja muiden syöttökenttien maksimipituuden.
  • min: Numero. Määrittää numeeristen ja päivämääräkenttien minimiarvon.
  • minLength: Numero. Määrittää tekstin ja muiden syöttökenttien minimipituuden.
  • multiple: Totuusarvo. Määrittää onko useita arvoja sallittu type="file" ja type="email"-kentille.
  • name: Merkkijono. Määrittää nimen tälle kentälle, joka lähetetään lomakkeessa.
  • onChange: Event käsittelijäfunktio. Vaaditaan kontrolloituihin kenttiin. Suoritetaan heti kun käyttäjä muuttaa kentän arvoa (esimerkiksi, suoritetaan jokaisella näppäinpainalluksella). Käyttäytyy kuten selaimen input tapahtuma.
  • onChangeCapture: Versio onChange:sta joka suoritetaan nappausvaiheessa.
  • onInput: Event käsittelijäfunktio. Suoritetaan heti kun käyttäjä muuttaa kentän arvoa. Historiallisista syistä, Reactissa on idiomaattista käyttää tämän tilalla onChange, joka toimii samanlaisesti.
  • onInputCapture: Versio onInput:sta joka suoritetaan nappausvaiheessa.
  • onInvalid: Event käsittelijäfunktio. Suoritetaan jos syöttökenttä epäonnistuu lomakkeen lähetyksessä. Toisin kuin selaimen sisäänrakennettu invalid-tapahtuma, Reactin onInvalid-tapahtuma kuplii.
  • onInvalidCapture: Versio onInvalid:sta joka suoritetaan nappausvaiheessa.
  • onSelect: Event käsittelijäfunktio. Suoritetaan kun valinta <input>-elementissä muuttuu. React laajentaa onSelect-tapahtuman myös tyhjälle valinnalle ja muokkauksille (jotka voivat vaikuttaa valintaan).
  • onSelectCapture: Versio onSelect:sta joka suoritetaan nappausvaiheessa.
  • pattern: Merkkijono. Määrittää mallin, joka value:n täytyy täyttää.
  • placeholder: Merkkijono. Näytetään himmennettynä kun syöttökentän arvo on tyhjä.
  • readOnly: Totuusarvo. Jos true, syöttökenttä ei ole muokattavissa käyttäjän toimesta.
  • required: Totuusarvo. Jos true, arvo täytyy antaa lomakkeen lähetyksessä.
  • size: Numero. Samanlainen kuin leveyden määrittäminen, mutta yksikkö riippuu kontrollista.
  • src: Merkkijono. Määrittää kuvan lähteen type="image"-kentälle.
  • step: Positiivinen numero tai 'any'-merkkijono. Määrittää etäisyyden kelvollisten arvojen välillä.
  • type: Merkkijono. Yksi syöttökenttien tyypeistä.
  • width: Merkkijono. Määrittää kuvan leveyden type="image"-kentälle.

Rajoitukset

  • Valintaruudut tarvitsevat checked (tai defaultChecked), ei value (tai defaultValue).
  • Jos tekstisyöttökenttä saa merkkijono value-propin, se käsitellään kontrolloituna.
  • Jos valintaruutu tai radiopainike saa boolean checked-propin, se käsitellään kontrolloituna.
  • Syöttökenttä ei voi olla sekä kontrolloitu että kontrolloimaton samaan aikaan.
  • Syöttökenttä ei voi vaihtaa kontrolloidusta kontrolloimattomaksi elinkaarensa aikana.
  • Jokainen kontrolloitu syöttökenttä tarvitsee onChange-käsittelijäfunktion, joka päivittää sen arvon synkronisesti.

Käyttö

Eri tyyppisten syöttökenttien näyttäminen

Näyttääksesi syöttökentän, renderöi <input>-komponentti. Oletuksena, se on tekstisyöttökenttä. Voit antaa type="checkbox" valintaruudulle, type="radio" radiopainikkeelle, tai yhden muista syöttökenttien tyypeistä.

export default function MyForm() {
  return (
    <>
      <label>
        Tekstisyöte: <input name="myInput" />
      </label>
      <hr />
      <label>
        Valintaruutu: <input type="checkbox" name="myCheckbox" />
      </label>
      <hr />
      <p>
        Monivalinta:
        <label>
          <input type="radio" name="myRadio" value="option1" />
          Valinta 1
        </label>
        <label>
          <input type="radio" name="myRadio" value="option2" />
          Valinta 2
        </label>
        <label>
          <input type="radio" name="myRadio" value="option3" />
          Valinta 3
        </label>
      </p>
    </>
  );
}


Syöttökentän otsikko

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

Jos et voi sisällyttää <input>-komponenttia <label>-komponenttiin, yhdistä ne antamalla sama ID <input id>-komponentille ja <label htmlFor>-komponentille. Välttääksesi konflikteja useiden yhden komponentin instanssien välillä, generoi tällainen ID useId-komponentilla.

import { useId } from 'react';

export default function Form() {
  const ageInputId = useId();
  return (
    <>
      <label>
        Etunimi:
        <input name="firstName" />
      </label>
      <hr />
      <label htmlFor={ageInputId}>Ikä:</label>
      <input id={ageInputId} name="age" type="number" />
    </>
  );
}


Oletusarvon tarjoaminen syöttökentälle

Voit vaihtoehtoisesti määrittää alkuarvon mille tahansa syöttökentälle. Anna se defaultValue-merkkijonona tekstisyöttökentille. Valintaruudut ja radiopainikkeet määrittävät alkuarvon defaultChecked-totuusarvona.

export default function MyForm() {
  return (
    <>
      <label>
        Text input: <input name="myInput" defaultValue="Some initial value" />
      </label>
      <hr />
      <label>
        Checkbox: <input type="checkbox" name="myCheckbox" defaultChecked={true} />
      </label>
      <hr />
      <p>
        Radio buttons:
        <label>
          <input type="radio" name="myRadio" value="option1" />
          Option 1
        </label>
        <label>
          <input
            type="radio"
            name="myRadio"
            value="option2"
            defaultChecked={true} 
          />
          Option 2
        </label>
        <label>
          <input type="radio" name="myRadio" value="option3" />
          Option 3
        </label>
      </p>
    </>
  );
}


Syöttökentän arvon lukeminen lomakkeen lähetyksessä

Lisää <form> syöttökenttien ympärille. Lisää myös <button type="submit">-komponentti sen sisään. Se kutsuu <form onSubmit>-käsittelijäfunktiota. Oletuksena, selain lähettää lomakedatan nykyiselle URL:lle ja päivittää sivun. Voit ohittaa tämän käyttämällä e.preventDefault(). Lue lomakedata new FormData(e.target):lla.

export default function MyForm() {
  function handleSubmit(e) {
    // Estä selainta lataamasta sivua uudelleen
    e.preventDefault();

    // Lue lomakedata
    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 });

    // Tai voit käsitellä sitä tavallisena objektina:
    const formJson = Object.fromEntries(formData.entries());
    console.log(formJson);
  }

  return (
    <form method="post" onSubmit={handleSubmit}>
      <label>
        Tekstisyöte: <input name="myInput" defaultValue="Some initial value" />
      </label>
      <hr />
      <label>
        Valintaruutu: <input type="checkbox" name="myCheckbox" defaultChecked={true} />
      </label>
      <hr />
      <p>
        Monivalinta:
        <label><input type="radio" name="myRadio" value="option1" /> Vaihtoehto 1</label>
        <label><input type="radio" name="myRadio" value="option2" defaultChecked={true} /> Vaihtoehto 2</label>
        <label><input type="radio" name="myRadio" value="option3" /> Vaihtoehto 3</label>
      </p>
      <hr />
      <button type="reset">Nollaa lomake</button>
      <button type="submit">Lähetä lomake</button>
    </form>
  );
}

Huomaa

Anna jokaiselle <input>:lle name, esimerkiksi <input name="firstName" defaultValue="Taylor" />. name-arvoa käytetään avaimena lomakedatassa, esimerkiksi { firstName: "Taylor" }.

Sudenkuoppa

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


Syöttökentän ohjaaminen tilamuuttujalla

Syöttökenttä kuten <input /> on kontrolloimaton. Vaikka antaisit alkuarvon kuten <input defaultValue="Alkuteksti" />, JSX:si määrittää vain alkuarvon. Se ei kontrolloi mitä arvoa sen pitäisi olla juuri nyt.

Renderöidäksesi kontrolloidun syöttökentän, anna sille value-prop. React pakottaa syöttökentän aina olemaan value jonka annoit. Yleensä, teet tämän määrittämällä tilamuuttujan:

function Form() {
const [firstName, setFirstName] = useState(''); // Määritä tilamuuttuja...
// ...
return (
<input
value={firstName} // ...pakota kentän arvo vastaamaan tilamuuttujaa...
onChange={e => setFirstName(e.target.value)} // ... ja päivitä tilamuuttuja jokaisella muutoksella!
/>
);
}

Kontrolloitu syöttökenttä on järkevä jos tarvitset tilamuuttujaa muutenkin—esimerkiksi, renderöidäksesi uudelleen käyttöliittymäsi jokaisella muutoksella:

function Form() {
const [firstName, setFirstName] = useState('');
return (
<>
<label>
Etunimi:
<input value={firstName} onChange={e => setFirstName(e.target.value)} />
</label>
{firstName !== '' && <p>Nimesi on {firstName}.</p>}
...

On myös hyödyllistä jos haluat tarjota useita tapoja muuttaa syöttökentän tilaa (esimerkiksi, klikkaamalla nappia):

function Form() {
// ...
const [age, setAge] = useState('');
const ageAsNumber = Number(age);
return (
<>
<label>
Ikä:
<input
value={age}
onChange={e => setAge(e.target.value)}
type="number"
/>
<button onClick={() => setAge(ageAsNumber + 10)}>
Lisää 10 vuotta
</button>

value jonka välität kontrolloiduille komponenteille ei saa olla undefined tai null. Jos tarvitset tyhjän alkuarvon (esimerkiksi, firstName-kentän alla), alusta tilamuuttujasi tyhjällä merkkijonolla ('').

import { useState } from 'react';

export default function Form() {
  const [firstName, setFirstName] = useState('');
  const [age, setAge] = useState('20');
  const ageAsNumber = Number(age);
  return (
    <>
      <label>
        Etunimi:
        <input
          value={firstName}
          onChange={e => setFirstName(e.target.value)}
        />
      </label>
      <label>
        Ikä:
        <input
          value={age}
          onChange={e => setAge(e.target.value)}
          type="number"
        />
        <button onClick={() => setAge(ageAsNumber + 10)}>
          Lisää 10 vuotta
        </button>
      </label>
      {firstName !== '' &&
        <p>Nimesi on {firstName}.</p>
      }
      {ageAsNumber > 0 &&
        <p>Ikäsi on {ageAsNumber}.</p>
      }
    </>
  );
}

Sudenkuoppa

Jos välität value-arvon ilman onChange:a, syöttökenttään ei voi kirjoittaa. Kun kontrolloit syöttökenttää välittämällä sille value-arvon, pakotat sen aina olemaan arvon jonka välitit. Joten jos välität tilamuuttujan value:n mutta unohdat päivittää tilamuuttujaa synkronisesti onChange-tapahtumakäsittelijässä, React palauttaa syöttökentän jokaisen näppäinpainalluksen jälkeen takaisin value:n arvoon jonka määritit.


Renderöinnin optimoiminen joka näppäinpainalluksella

Kun käytät kontrolloitua syöttökenttää, asetat tilamuuttujan jokaisella näppäinpainalluksella. Jos komponentti joka sisältää tilamuuttujan uudelleen renderöi suuren puun, tästä saattaa tulla hidasta. On muutamia tapoja joilla voit optimoida uudelleen renderöimisen suorityskykyä.

Esimerkiksi, oletetaan että aloitat lomakkeella joka uudelleen renderöi kaiken sisällön jokaisella näppäinpainalluksella:

function App() {
const [firstName, setFirstName] = useState('');
return (
<>
<form>
<input value={firstName} onChange={e => setFirstName(e.target.value)} />
</form>
<PageContent />
</>
);
}

Sillä <PageContent /> ei nojaa syöttökentän tilaan, voit siirtää syöttökentän tilan omaan komponenttiinsa:

function App() {
return (
<>
<SignupForm />
<PageContent />
</>
);
}

function SignupForm() {
const [firstName, setFirstName] = useState('');
return (
<form>
<input value={firstName} onChange={e => setFirstName(e.target.value)} />
</form>
);
}

Tämä parantaa suorituskykyä merkittävästi koska nyt vain SignupForm uudelleen renderöi jokaisella näppäinpainalluksella.

Jos ei ole tapaa välttää uudelleen renderöintiä (esimerkiksi, jos PageContent riippuu hakukentän arvosta), useDeferredValue antaa sinun pitää kontrolloidun syöttökentän reagoivana jopa suuren uudelleen renderöinnin keskellä.


Vianmääritys

Tekstikenttäni ei päivity kun kirjoitan siihen

Jos renderöit syöttökentän value-arvolla mutta ilman onChange:a, näet virheen konsolissa:

// 🔴 Bugi: kontrolloitu tekstisyöttökenttä ilman onChange-käsittelijää
<input value={something} />
Konsoli
You provided a value prop to a form field without an onChange handler. This will render a read-only field. If the field should be mutable use defaultValue. Otherwise, set either onChange or readOnly.

Kuten virheviesti ehdottaa, jos halusit vain määrittää alkuarvon, välitä defaultValue sen sijaan:

// ✅ Hyvä: kontrolloimaton syöttökenttä alkuarvolla
<input defaultValue={something} />

Jos haluat kontrolloida tätä syöttökenttää tilamuuttujalla, määritä onChange-käsittelijä:

// ✅ Hyvä: kontrolloitu syöttökenttä onChange-käsittelijällä
<input value={something} onChange={e => setSomething(e.target.value)} />

Jos arvo on tarkoituksella vain luettava, lisää readOnly-prop.

// ✅ Hyvä: vain luku -syöttökenttä ilman onChange-käsittelijää
<input value={something} readOnly={true} />

Valintaruutuni ei päivity kun painan siitä

Jos renderöit valintaruudun checked-arvolla mutta ilman onChange:a, näet virheen konsolissa:

// 🔴 Bugi: kontrolloitu valintaruutu ilman onChange-käsittelijää
<input type="checkbox" checked={something} />
Konsoli
You provided a checked prop to a form field without an onChange handler. This will render a read-only field. If the field should be mutable use defaultChecked. Otherwise, set either onChange or readOnly.

Kuten virheviesti ehdottaa, jos halusit vain määrittää alkuarvon, välitä defaultChecked sen sijaan:

// ✅ Hyvä: kontrolloimaton valintaruutu alkuarvolla
<input type="checkbox" defaultChecked={something} />

Jos haluat kontrolloida tätä valintaruutua tilamuuttujalla, määritä onChange-käsittelijä:

// ✅ Hyvä: kontrolloitu valintaruutu onChange-käsittelijällä
<input type="checkbox" checked={something} onChange={e => setSomething(e.target.checked)} />

Sudenkuoppa

Sinun tulee lukea e.target.checked eikä e.target.value valintaruuduille.

Jos valintaruutu on tarkoituksella vain luettava, lisää readOnly-prop virheen poistamiseksi:

// ✅ Hyvä: vain luku -valintaruutu ilman onChange-käsittelijää
<input type="checkbox" checked={something} readOnly={true} />

Syötön kursori hyppää alkuun jokaisen näppäinpainalluksen yhteydessä

Jos kontrolloit syöttökenttää, sinun täytyy päivittää sen tilamuuttuja syöttökentän arvoksi DOM:sta onChange:n aikana.

Et voi päivittää sitä joksikin muuksi kuin e.target.value (tai e.target.checked valintaruuduille):

function handleChange(e) {
// 🔴 Bugi: kentän päivittäminen joksikin muuksi kuin e.target.value
setFirstName(e.target.value.toUpperCase());
}

Et voi myöskään päivittää sitä asynkronisesti:

function handleChange(e) {
// 🔴 Bugi: kentän päivittäminen asynkronisesti
setTimeout(() => {
setFirstName(e.target.value);
}, 100);
}

Korjataksesi koodisi, päivitä se synkronisesti e.target.value:lla:

function handleChange(e) {
// ✅ Kontrolloidun kentän päivittäminen e.target.value:lla synkronisesti
setFirstName(e.target.value);
}

Jos tämä ei korjaa ongelmaa, on mahdollista että syöttökenttä poistetaan ja lisätään takaisin DOM:iin jokaisella näppäinpainalluksella. Tämä voi tapahtua jos olet vahingossa nollannut tilan jokaisella uudelleen renderöinnillä, esimerkiksi jos syöttökenttä tai jokin sen vanhemmista saa aina erilaisen key-attribuutin, tai jos upotat komponenttifunktioiden määrittelyjä (jota ei tueta ja aiheuttaa “sisemmän” komponentin aina olevan eri puu).


Saan virheen: “A component is changing an uncontrolled input to be controlled”

Jos tarjoat value:n komponentille, sen täytyy pysyä merkkijonona koko elinkaarensa ajan.

Et voi välittää value={undefined} ensin ja myöhemmin välittää value="some string" koska React ei tiedä haluatko komponentin olevan kontrolloimaton vai kontrolloitu. Kontrolloidun komponentin tulisi aina saada merkkijonona value, ei null tai undefined.

Jos value tulee API:sta tai tilamuuttujasta, se voi olla alustettu null tai undefined. Tässä tapauksessa, joko aseta se tyhjäksi merkkijonoksi ('') aluksi, tai välitä value={someValue ?? ''} varmistaaksesi, että value on merkkijono.

Vastaavasti, jos välität checked propsin valintaruudulle, varmista että se on aina totuusarvo.