<input>
Komponen bawaan browser <input>
memungkinkan Anda merender berbagai jenis input form.
<input />
Referensi
<input>
Untuk menampilkan sebuah masukan, render komponen bawaan browser <input>
.
<input name="myInput" />
Lihat lebih banyak contoh di bawah ini.
Props
<input>
mendukung semua element props yang umum.
Anda dapat membuat sebuah masukan yang terkontrol melalui satu dari beberapa props berikut:
checked
: Sebuah boolean. Untuk masukan checkbox atau tombol radio, mengontrol apakah itu dipilih.value
: Sebuah string. Untuk sebuah masukan text, mengontrol text. (Untuk tombol radio, menentukan data form.)
Ketika Anda mengoper salah satu dari mereka, Anda juga harus mengoper sebuah onChange
handler yang memperbarui nilai yang dioper.
Props <input>
ini hanya relevan untuk input yang tidak dikontrol:
defaultChecked
: Sebuah boolean. Menentukan nilai awal dari masukantype="checkbox"
dantype="radio"
.defaultValue
: Sebuah string. Menentukan nilai awal dari masukan sebuah text.
Props <input>
ini relevan untuk input tidak terkontrol dan input terkontrol:
accept
: Sebuah string. Menentukan tipe file mana yang diterima oleh masukantype="file"
.alt
: Sebuah string. Menentukan teks gambar alternatif untuk masuktype="image"
.capture
: Sebuah string. Menentukan media (mikrofon, video, atau kamera) yang ditangkap oleh masukantype="file"
.autoComplete
: Sebuah string. Menentukan salah satu kemungkinan perilaku autocomplete.autoFocus
: Sebuah boolean. Jikatrue
, React akan memfokuskan elemen saat pasang.dirname
: Sebuah string. Menentukan nama bidang form untuk arah elemen.disabled
: Sebuah boolean. Jikatrue
, masukan tidak akan interaktif dan akan tampak redup.children
:<input>
tidak menerima children.form
: Sebuah string. Menentukanid
dari<form>
milik masukan ini. Jika dihilangkan, menggunakan parent form terdekat.formAction
: Sebuah string. Menimpa parent<form action>
daritype="submit"
dantype="image"
.formEnctype
: Sebuah string. Menimpa parent<form enctype>
daritype="submit"
dantype="image"
.formMethod
: Sebuah string. Menimpa parent<form method>
daritype="submit"
dantype="image"
.formNoValidate
: Sebuah string. Menimpa parent<form noValidate>
daritype="submit"
dantype="image"
.formTarget
: Sebuah string. Menimpa parent<form target>
daritype="submit"
dantype="image"
.height
: Sebuah string. Menentukan tinggi dari gambar untuktype="image"
.list
: Sebuah string. Menentukanid
dari<datalist>
dengan opsi autocomplete.max
: Sebuah angka. Menentukan nilai maksimum masukan numerik dan waktu.maxLength
: Sebuah angka. Menentukan panjang maksimum teks dan masukan lainnya.min
: Sebuah angka. Menentukan nilai minimum masukan numerik dan waktu.minLength
: Sebuah angka. Menentukan panjang minimum teks dan masukan lainnya.multiple
: Sebuah boolean. Menentukan apakah beberapa nilai diperbolehkan untuk<type="file"
dantype="email"
.name
: Sebuah string. Menentukan nama dari masukan yang disubmit dengan form.onChange
: Sebuah fungsiEvent
handler. Dibutuhkan untuk masukan yang terkontrol. Langsung aktif ketika nilai masukan diubah oleh pengguna (sebagai contoh, menyala di setip penekanan tombol). Berperilaku seperti eventinput
.onChangeCapture
: Sebuha versi darionChange
yang aktif dalam fase menangkap.onInput
: Sebuah fungsiEvent
handler. Langsung aktif ketika nilainya diubah oleh pengguna. Untuk alasan historis, dalam React menggunakanonChange
sebagai gantinya yang berfungsi serupa adalah idiomatis.onInputCapture
: A version ofonInput
that fires in the capture phase.onInvalid
: Sebuah fungsiEvent
handler. Aktif jika sebuah masukan gagal divalidasi ketika pengiriman form. Tidak seperti eventinvalid
bawaan, ReactonInvalid
berbentuk event bubbles.onInvalidCapture
: Sebuah versi darionInvalid
yang aktif didalam fase menangkap.onSelect
: Sebuah fungsiEvent
handler. Aktif setelah pemilihan di dalam<input>
berubah. React memperluas eventonSelect
untuk juga mengaktifkan pemilihan kosong dan pada pengeditan (yang dapat memengaruhi pemilihan).onSelectCapture
: Sebuah versi darionSelect
yang aktif ketika fase menangkap.pattern
: Sebuah string. Menentukan pola yang harus cocok denganvalue
.placeholder
: Sebuah string. Ditampilkan dalam warna redup saat nilai input kosong.readOnly
: Sebuah boolean. Jikatrue
, masukan tidak dapat diedit oleh pengguna.required
: Sebuah boolean. Jikatrue
, nilai harus diberikan untuk form yang akan dikirim.size
: Sebuah angka. Mirip dengan pengaturan lebar, tetapi unit tergantung pada kontrol.src
: Sebuah string. Menentukan sumber gambar untuk masukantype="image"
.step
: Angka positif atau string'any'
. Menentukan jarak antara nilai yang valid.type
: Sebuah string. Satu dari tipe masukan.width
: Sebuah string. Menentukan lebar gambar untuk masukantype="image"
.
Peringatan
- Checkbox harus
checked
(ataudefaultChecked
), bukanvalue
(ataudefaultValue
). - Jika sebuah masukan text menerima sebuah prop string
value
, itu akan diperlakukan sebagai terkontrol. - Jika sebuah checkbox atau sebuah tombol radio menerima prop boolean
checked
, itu akan diperlakukan sebagai terkontrol. - Masukan tidak dapat dikontrol dan tidak dikontrol secara bersamaan.
- Masukan tidak dapat beralih antara dikontrol atau tidak dikontrol selama masa pakainya.
- Setiap masukan yang dikontrol membutuhkan event handler
onChange
yang secara sinkron memperbarui nilai pendukungnya.
Penggunaan
Displaying inputs of different types
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> </> ); }
Providing a label for an input
Typically, you will place every <input>
inside a <label>
tag. This tells the browser that this label is associated with that input. When the user clicks the label, the browser will automatically focus the input. It’s also essential for accessibility: a screen reader will announce the label caption when the user focuses the associated input.
If you can’t nest <input>
into a <label>
, associate them by passing the same ID to <input id>
and <label htmlFor>
. To avoid conflicts between multiple instances of one component, generate such an ID with useId
.
import { useId } from 'react'; export default function Form() { const ageInputId = useId(); return ( <> <label> Your first name: <input name="firstName" /> </label> <hr /> <label htmlFor={ageInputId}>Your age:</label> <input id={ageInputId} name="age" type="number" /> </> ); }
Providing an initial value for an input
You can optionally specify the initial value for any input. Pass it as the defaultValue
string for text inputs. Checkboxes and radio buttons should specify the initial value with the defaultChecked
boolean instead.
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> </> ); }
Reading the input values when submitting a form
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> ); }
Controlling an input with a state variable
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> } </> ); }
Optimizing re-rendering on every keystroke
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.
Troubleshooting
My text input doesn’t update when I type into it
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} />
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} />
My checkbox doesn’t update when I click on it
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} />
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)} />
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} />
My input caret jumps to the beginning on every keystroke
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).
I’m getting an error: “A component is changing an uncontrolled input to be controlled”
If you provide a value
to the component, it must remain a string throughout its lifetime.
You cannot pass value={undefined}
first and later pass value="some string"
because React won’t know whether you want the component to be uncontrolled or controlled. A controlled component should always receive a string value
, not null
or undefined
.
If your value
is coming from an API or a state variable, it might be initialized to null
or undefined
. In that case, either set it to an empty string (''
) initially, or pass value={someValue ?? ''}
to ensure value
is Sebuah string.
Similarly, if you pass checked
to a checkbox, ensure it’s always Sebuah boolean.