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

<input />

Viite

<input>

To display an input, render the built-in browser <input> component.

<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. Specifies one of the possible autocomplete behaviors.
  • 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. Overrides the parent <form enctype> for type="submit" and type="image".
  • 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. Specifies the maximum value of numerical and datetime inputs.
  • maxLength: Numero. Specifies the maximum length of text and other inputs.
  • min: Numero. Specifies the minimum value of numerical and datetime inputs.
  • minLength: Numero. Specifies the minimum length of text and other inputs.
  • multiple: Totuusarvo. Specifies whether multiple values are allowed for <type="file" and type="email".
  • 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). Behaves like the browser input event.
  • 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. Fires if an input fails validation on form submit. Unlike the built-in invalid event, the React onInvalid event bubbles.
  • onInvalidCapture: Versio onInvalid:sta joka suoritetaan nappausvaiheessa.
  • onSelect: Event käsittelijäfunktio. Fires after the selection inside the <input> changes. React extends the onSelect event to also fire for empty selection and on edits (which may affect the selection).
  • onSelectCapture: Versio onSelect:sta joka suoritetaan nappausvaiheessa.
  • pattern: Merkkijono. Specifies the pattern that the value must match.
  • placeholder: Merkkijono. Displayed in a dimmed color when the input value is empty.
  • readOnly: Totuusarvo. If true, the input is not editable by the user.
  • required: Totuusarvo. If true, the value must be provided for the form to submit.
  • size: Numero. Similar to setting width, but the unit depends on the control.
  • src: Merkkijono. Specifies the image source for a type="image" input.
  • step: A positive number or an 'any' string. Specifies the distance between valid values.
  • type: Merkkijono. One of the input types.
  • width: Merkkijono. Specifies the image width for a type="image" input.

Rajoitukset

  • Checkboxes need checked (or defaultChecked), not value (or defaultValue).
  • If a text input receives a string value prop, it will be treated as controlled.
  • If a checkbox or a radio button receives a boolean checked prop, it will be treated as controlled.
  • An input can’t be both controlled and uncontrolled at the same time.
  • An input cannot switch between being controlled or uncontrolled over its lifetime.
  • Every controlled input needs an onChange event handler that synchronously updates its backing value.

Käyttö

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

To display an input, render an <input> component. By default, it will be a text input. You can pass type="checkbox" for a checkbox, type="radio" for a radio button, or one of the other input types.

export default function MyForm() {
  return (
    <>
      <label>
        Text input: <input name="myInput" />
      </label>
      <hr />
      <label>
        Checkbox: <input type="checkbox" name="myCheckbox" />
      </label>
      <hr />
      <p>
        Radio buttons:
        <label>
          <input type="radio" name="myRadio" value="option1" />
          Option 1
        </label>
        <label>
          <input type="radio" name="myRadio" value="option2" />
          Option 2
        </label>
        <label>
          <input type="radio" name="myRadio" value="option3" />
          Option 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ä

Add a <form> around your inputs with a <button type="submit"> inside. It will call your <form onSubmit> event handler. By default, the browser will send the form data to the current URL and refresh the page. You can override that behavior by calling e.preventDefault(). Read the form data with new FormData(e.target).

export default function MyForm() {
  function handleSubmit(e) {
    // Prevent the browser from reloading the page
    e.preventDefault();

    // Read the form data
    const form = e.target;
    const formData = new FormData(form);

    // You can pass formData as a fetch body directly:
    fetch('/some-api', { method: form.method, body: formData });

    // Or you can work with it as a plain object:
    const formJson = Object.fromEntries(formData.entries());
    console.log(formJson);
  }

  return (
    <form method="post" onSubmit={handleSubmit}>
      <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>
      <hr />
      <button type="reset">Reset form</button>
      <button type="submit">Submit form</button>
    </form>
  );
}

Huomaa

Give a name to every <input>, for example <input name="firstName" defaultValue="Taylor" />. The name you specified will be used as a key in the form data, for example { firstName: "Taylor" }.

Sudenkuoppa

By default, any <button> inside a <form> will submit it. This can be surprising! If you have your own custom Button React component, consider returning <button type="button"> instead of <button>. Then, to be explicit, use <button type="submit"> for buttons that are supposed to submit the form.


Syöttökentän ohjaaminen tilamuuttujalla

An input like <input /> is uncontrolled. Even if you pass an initial value like <input defaultValue="Initial text" />, your JSX only specifies the initial value. It does not control what the value should be right now.

To render a controlled input, pass the value prop to it (or checked for checkboxes and radios). React will force the input to always have the value you passed. Usually, you would do this by declaring a state variable:

function Form() {
const [firstName, setFirstName] = useState(''); // Declare a state variable...
// ...
return (
<input
value={firstName} // ...force the input's value to match the state variable...
onChange={e => setFirstName(e.target.value)} // ... and update the state variable on any edits!
/>
);
}

A controlled input makes sense if you needed state anyway—for example, to re-render your UI on every edit:

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

It’s also useful if you want to offer multiple ways to adjust the input state (for example, by clicking a button):

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

The value you pass to controlled components should not be undefined or null. If you need the initial value to be empty (such as with the firstName field below), initialize your state variable to an empty string ('').

import { useState } from 'react';

export default function Form() {
  const [firstName, setFirstName] = useState('');
  const [age, setAge] = useState('20');
  const ageAsNumber = Number(age);
  return (
    <>
      <label>
        First name:
        <input
          value={firstName}
          onChange={e => setFirstName(e.target.value)}
        />
      </label>
      <label>
        Age:
        <input
          value={age}
          onChange={e => setAge(e.target.value)}
          type="number"
        />
        <button onClick={() => setAge(ageAsNumber + 10)}>
          Add 10 years
        </button>
      </label>
      {firstName !== '' &&
        <p>Your name is {firstName}.</p>
      }
      {ageAsNumber > 0 &&
        <p>Your age is {ageAsNumber}.</p>
      }
    </>
  );
}

Sudenkuoppa

If you pass value without onChange, it will be impossible to type into the input. When you control an input by passing some value to it, you force it to always have the value you passed. So if you pass a state variable as a value but forget to update that state variable synchronously during the onChange event handler, React will revert the input after every keystroke back to the value that you specified.


Renderöinnin optimoiminen joka näppäinpainalluksella

When you use a controlled input, you set the state on every keystroke. If the component containing your state re-renders a large tree, this can get slow. There’s a few ways you can optimize re-rendering performance.

For example, suppose you start with a form that re-renders all page content on every keystroke:

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

Since <PageContent /> doesn’t rely on the input state, you can move the input state into its own component:

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

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

This significantly improves performance because now only SignupForm re-renders on every keystroke.

If there is no way to avoid re-rendering (for example, if PageContent depends on the search input’s value), useDeferredValue lets you keep the controlled input responsive even in the middle of a large re-render.


Vianmääritys

Tekstikenttäni ei päivity kun kirjoitan siihen

If you render an input with value but no onChange, you will see an error in the console:

// 🔴 Bug: controlled text input with no onChange handler
<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.

As the error message suggests, if you only wanted to specify the initial value, pass defaultValue instead:

// ✅ Good: uncontrolled input with an initial value
<input defaultValue={something} />

If you want to control this input with a state variable, specify an onChange handler:

// ✅ Good: controlled input with onChange
<input value={something} onChange={e => setSomething(e.target.value)} />

If the value is intentionally read-only, add a readOnly prop to suppress the error:

// ✅ Good: readonly controlled input without on change
<input value={something} readOnly={true} />

Valintaruutuni ei päivity kun painan siitä

If you render a checkbox with checked but no onChange, you will see an error in the console:

// 🔴 Bug: controlled checkbox with no onChange handler
<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.

As the error message suggests, if you only wanted to specify the initial value, pass defaultChecked instead:

// ✅ Good: uncontrolled checkbox with an initial value
<input type="checkbox" defaultChecked={something} />

If you want to control this checkbox with a state variable, specify an onChange handler:

// ✅ Good: controlled checkbox with onChange
<input type="checkbox" checked={something} onChange={e => setSomething(e.target.checked)} />

Sudenkuoppa

You need to read e.target.checked rather than e.target.value for checkboxes.

If the checkbox is intentionally read-only, add a readOnly prop to suppress the error:

// ✅ Good: readonly controlled input without on change
<input type="checkbox" checked={something} readOnly={true} />

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

If you control an input, you must update its state variable to the input’s value from the DOM during onChange.

You can’t update it to something other than e.target.value (or e.target.checked for checkboxes):

function handleChange(e) {
// 🔴 Bug: updating an input to something other than e.target.value
setFirstName(e.target.value.toUpperCase());
}

You also can’t update it asynchronously:

function handleChange(e) {
// 🔴 Bug: updating an input asynchronously
setTimeout(() => {
setFirstName(e.target.value);
}, 100);
}

To fix your code, update it synchronously to e.target.value:

function handleChange(e) {
// ✅ Updating a controlled input to e.target.value synchronously
setFirstName(e.target.value);
}

If this doesn’t fix the problem, it’s possible that the input gets removed and re-added from the DOM on every keystroke. This can happen if you’re accidentally resetting state on every re-render, for example if the input or one of its parents always receives a different key attribute, or if you nest component function definitions (which is not supported and causes the “inner” component to always be considered a different tree).


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.