<input>
Komponen bawaan peramban <input>
memungkinkan Anda me-render berbagai jenis masukan form.
<input />
Referensi
<input>
Untuk menampilkan sebuah masukan, render komponen bawaan peramban <input>
.
<input name="myInput" />
Lihat lebih banyak contoh di bawah ini.
Props
<input>
mendukung semua element props yang umum.
formAction
: Sebuah string atau fungsi. Menimpa <form action>
induk untuk type="submit"
dan type="image"
. Ketika URL dioper ke action
form akan memiliki perilaku sebagai form standar HTML. Ketika fungsi dioper ke formAction
fungsi akan menangani kiriman form. Lihat <form action>
.
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 teks, mengontrol teks. (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 masukan yang tidak dikontrol:
defaultChecked
: Sebuah boolean. Menentukan nilai awal dari masukantype="checkbox"
dantype="radio"
.defaultValue
: Sebuah string. Menentukan nilai awal dari masukan sebuah teks.
Props <input>
ini relevan untuk masukan tidak terkontrol dan masukan 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"
.
Caveats
- Checkbox harus
checked
(ataudefaultChecked
), bukanvalue
(ataudefaultValue
). - Jika sebuah masukan teks 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
Menampilkan masukan dari berbagai jenis
Untuk menampilkan masukan, render sebuah komponen <input>
. Secara default, itu akan menjadi masukan teks. Anda dapat mengopen type="checkbox"
untuk sebuah checkbox, type="radio"
untuk sebuah tombol radio, atau salah satu dari jenis masukan lainnya.
export default function MyForm() { return ( <> <label> Masukan teks: <input name="myInput" /> </label> <hr /> <label> Checkbox: <input type="checkbox" name="myCheckbox" /> </label> <hr /> <p> Tombol radio: <label> <input type="radio" name="myRadio" value="option1" /> Pilihan 1 </label> <label> <input type="radio" name="myRadio" value="option2" /> Pilihan 2 </label> <label> <input type="radio" name="myRadio" value="option3" /> Pilihan 3 </label> </p> </> ); }
Memberikan label untuk sebuah masukan
Biasanya, Anda akan menaruh setiap <input>
di dalam sebuah tag <label>
. Ini memberi tahu peramban bahwa label ini dikaitkan dengan masukan itu. Saat pengguna melakukan klik pada label, peramban akan secara otomatis memfokuskan input. Ini juga penting untuk aksesibilitas: pembaca layar akan memberitahukan keterangan label saat pengguna memfokuskan masukan terkait.
Jika Anda tidak dapat menumpuk <input>
pada sebuah <label>
, katikan keduanya dengan mengoper ID yang sama ke <input id>
dan <label htmlFor>
. Untuk menghindari konflik antara beberapa instance dari satu komponen, buat ID tersebut dengan useId
.
import { useId } from 'react'; export default function Form() { const ageInputId = useId(); return ( <> <label> Nama depan Anda: <input name="firstName" /> </label> <hr /> <label htmlFor={ageInputId}>Umur Anda:</label> <input id={ageInputId} name="age" type="number" /> </> ); }
Memberikan nilai awal untuk sebuah masukan
Secara opsional Anda dapat menentukan nilai awal untuk masukan apa pun. Berikan sebagai string defaultValue
untuk masukan teks. Sedangkan checkboxes dan tombol radio harus menentukan nilai awal dengan boolean defaultChecked
.
export default function MyForm() { return ( <> <label> Masukan teks: <input name="myInput" defaultValue="Beberapa nilai awal" /> </label> <hr /> <label> Checkbox: <input type="checkbox" name="myCheckbox" defaultChecked={true} /> </label> <hr /> <p> Tombol radio: <label> <input type="radio" name="myRadio" value="option1" /> Pilihan 1 </label> <label> <input type="radio" name="myRadio" value="option2" defaultChecked={true} /> Pilihan 2 </label> <label> <input type="radio" name="myRadio" value="option3" /> Pilihan 3 </label> </p> </> ); }
Membaca nilai input saat mengirimkan form
Tambahkan sebuah <form>
disekitar masukan Anda dengan <button type="submit">
di dalamnya. Ini akan memanggil event handler <form onSubmit>
. Secara default, peramban akan mengirimkan data form ke URL saat ini dan menyegarkan halaman. Anda dapat menimpa perilaku tersebut dengan memanggil e.preventDefault()
. Baca data form dengan new FormData(e.target)
.
export default function MyForm() { function handleSubmit(e) { // Cegah peramban memuat ulang halaman e.preventDefault(); // Membaca data form const form = e.target; const formData = new FormData(form); // Anda dapat mengoper formData sebagai fetch body secara langsung: fetch('/some-api', { method: form.method, body: formData }); // Atau Anda dapat mengerjakannya sebagai objek biasa: const formJson = Object.fromEntries(formData.entries()); console.log(formJson); } return ( <form method="post" onSubmit={handleSubmit}> <label> Masukan teks: <input name="myInput" defaultValue="Beberapa masukan awal" /> </label> <hr /> <label> Checkbox: <input type="checkbox" name="myCheckbox" defaultChecked={true} /> </label> <hr /> <p> Tombol radio: <label><input type="radio" name="myRadio" value="option1" /> Pilihan 1</label> <label><input type="radio" name="myRadio" value="option2" defaultChecked={true} /> Pilihan 2</label> <label><input type="radio" name="myRadio" value="option3" /> Pilihan 3</label> </p> <hr /> <button type="reset">Reset form</button> <button type="submit">Kirim form</button> </form> ); }
Mengontrol input dengan variabel status
Sebuah masukan seperti <input />
tidaklah terkontrol. Bahkan jika Anda memberikan sebuah nilai awal seperti <input defaultValue="Teks awal" />
, JSX Anda hanya menentukan nilai awal. Tidak mengontrol apa seharusnya nilai sekarang.
Untuk render sebuah masukan terkontrol, oper prop value
ke dalamnya (atau checked
untuk checkbox and radio). React akan memaksa masukan untuk selalu memiliki value
yang Anda berikan. Biasanya, Anda akan melakukan ini dengan mendeklarasikan sebuah variable state:
function Form() {
const [firstName, setFirstName] = useState(''); // Deklarasikan variabel state...
// ...
return (
<input
value={firstName} // ...memaksa nilai masukan untuk cocok dengan variabel state...
onChange={e => setFirstName(e.target.value)} // ... dan perbarui variabel state pada setiap pengeditan!
/>
);
}
Bagaimanapun sebuah masukan terkontrol masuk akal jika Anda membutuhkan state—contohnya, untuk render-ing ulang UI Anda pada setiap pengeditan:
function Form() {
const [firstName, setFirstName] = useState('');
return (
<>
<label>
Nama Anda:
<input value={firstName} onChange={e => setFirstName(e.target.value)} />
</label>
{firstName !== '' && <p>Nama Anda adalah {firstName}.</p>}
...
Ini juga berguna jika Anda ingin menawarkan berbagai cara untuk menyesuaikan state masukan (contohnya, dengan mengeklik tombol):
function Form() {
// ...
const [age, setAge] = useState('');
const ageAsNumber = Number(age);
return (
<>
<label>
Umur:
<input
value={age}
onChange={e => setAge(e.target.value)}
type="number"
/>
<button onClick={() => setAge(ageAsNumber + 10)}>
Tambah 10 tahun
</button>
value
yang Anda berikan ke komponen terkontrol tidak boleh undefined
or null
. Jika Anda memerlukan nilai awal kosong (seperti dengan kolom firstName
di bawah), inisialisasi variabel state Anda ke string kosong (''
).
import { useState } from 'react'; export default function Form() { const [firstName, setFirstName] = useState(''); const [age, setAge] = useState('20'); const ageAsNumber = Number(age); return ( <> <label> Nama Anda: <input value={firstName} onChange={e => setFirstName(e.target.value)} /> </label> <label> Umur: <input value={age} onChange={e => setAge(e.target.value)} type="number" /> <button onClick={() => setAge(ageAsNumber + 10)}> Tambah 10 tahun </button> </label> {firstName !== '' && <p>Nama Anda adalah {firstName}.</p> } {ageAsNumber > 0 && <p>Umur Anda adalah {ageAsNumber}.</p> } </> ); }
Mengoptimalkan render-ing ulang pada setiap penekanan tombol
Ketika Anda menggunakan masukan terkontrol, Anda mengatur state pada setiap penekanan tombol. Jika komponen yang berisi state Anda me-render ulang pohon besar, ini bisa menjadi lambat. Ada beberapa cara untuk mengoptimalkan kinerja render-ing ulang.
Contohnya, misalkan Anda mulai dengan form yang me-render ulang semua konten halaman pada setiap penekanan tombol:
function App() {
const [firstName, setFirstName] = useState('');
return (
<>
<form>
<input value={firstName} onChange={e => setFirstName(e.target.value)} />
</form>
<PageContent />
</>
);
}
Karena <PageContent />
tidak bergantung pada masukan state, Anda dapat memindahkan masukan state ke dalam komponennya sendiri:
function App() {
return (
<>
<SignupForm />
<PageContent />
</>
);
}
function SignupForm() {
const [firstName, setFirstName] = useState('');
return (
<form>
<input value={firstName} onChange={e => setFirstName(e.target.value)} />
</form>
);
}
Ini secara signifikan meningkatkan kinerja karena sekarang hanya SignupForm
yang di-render ulang pada setiap penekanan tombol.
Jika tidak ada cara untuk menghindari pe-render-an ulang (contohnya, jika PageContent
bergantung pada nilai masukan pencarian), useDeferredValue
memungkinkan Anda menjaga masukan yang dikontrol tetap responsif bahkan di tengah render ulang yang besar.
Penyelesaian masalah
Masukan teks saya tidak diperbarui saat saya mengetiknya
Jika Anda me-render masukan dengan value
tetapi tanpa onChange
, Anda akan melihat kesalahan di konsol:
// 🔴 Bug: masukan teks terkontrol tanpa handler onChange
<input value={something} />
value
ke kolom form tanpa handler onChange
. Ini akan membuat bidang read-only. Jika bidang harus dapat diubah, gunakan defaultValue
. Jika tidak, tetapkan onChange
atau readOnly
.Seperti yang disarankan oleh pesan kesalahan, jika Anda hanya ingin menentukan nilai awal, berikan defaultValue
sebagai gantinya:
// ✅ Bagus: masukan tidal terkontrol dengan sebuah nilai awal
<input defaultValue={something} />
Jika Anda ingin mengontrol masukan ini menggunakan sebuah variabel state, tentukan sebuah handler onChange
:
// ✅ Bagus: masukan terkontrol dengan onChange
<input value={something} onChange={e => setSomething(e.target.value)} />
Jika nilainya sengaja read-only, tambahkan prop readOnly
untuk mendiamkan kesalahan:
// ✅ Bagus: masukan yang dikontrol secara readonly tanpa perubahan
<input value={something} readOnly={true} />
Checkbox saya tidak diperbarui ketika saya mengkliknya
Jika Anda me-render kotak checkbox dengan checked
tetapi tanpa onChange
, Anda akan melihat kesalahan di konsol:
// 🔴 Bug: checkbox terkontrol tanpa handler onChange
<input type="checkbox" checked={something} />
checked
ke kolom form tanpa handler onChange
. Ini akan membuat bidang read-only. Jika bidang harus dapat diubah, gunakan defaultChecked
. Jika tidak, tetapkan onChange
atau readOnly
.Seperti yang disarankan oleh pesan kesalahan, jika Anda hanya ingin menentukan nilai awal, berikan defaultValue
sebagai gantinya:
// ✅ Bagus: checkbox tidak terkontrol dengan nilai awal
<input type="checkbox" defaultChecked={something} />
Jika Anda ingin mengontrol masukan checkbox ini menggunakan sebuah variabel state, tentukan sebuah handler onChange
:
// ✅ Bagus: checkbox terkontrol dengan onChange
<input type="checkbox" checked={something} onChange={e => setSomething(e.target.checked)} />
Jika checkbox sengaja read-only, tambahkan prop readOnly
untuk mendiamkan kesalahan:
// ✅ Bagus: readonly controlled input without on change
<input type="checkbox" checked={something} readOnly={true} />
Tanda sisipan saya melompat ke awal pada setiap penekanan tombol
Jika Anda mengontrol sebuah masukan, Anda harus memperbarui variabel state-nya ke nilai masukan dari DOM selama onChange
.
Anda tidak dapat memperbaruinya menjadi sesuatu selain e.target.value
(atau e.target.checked
untuk checkbox):
function handleChange(e) {
// 🔴 Bug: memperbarui masukan ke sesuatu selain e.target.value
setFirstName(e.target.value.toUpperCase());
}
Anda juga tidak dapat memperbaruinya secara asinkron:
function handleChange(e) {
// 🔴 Bug: memperbarui masukan secara asinkron
setTimeout(() => {
setFirstName(e.target.value);
}, 100);
}
Untuk memperbaiki kode Anda, perbarui secara sinkron ke e.target.value
:
function handleChange(e) {
// ✅ Memperbarui input terkontrol ke e.target.value secara sinkron
setFirstName(e.target.value);
}
Jika ini tidak menyelesaikan masalah, mungkin saja masukan dihapus dan ditambahkan kembali dari DOM pada setiap penekanan tombol. Ini dapat terjadi jika Anda secara tidak sengaja menyetel ulang state pada setiap render ulang, contohnya jika masukan atau salah satu parentnya selalu menerima atribut key
yang berbeda, atau jika Anda menyusun definisi fungsi komponen (yang tidak didukung dan menyebabkan komponen “dalam” selalu dianggap pohon yang berbeda).
Saya menerima pesan kesalahan: “Komponen sedang mengubah masukan yang tidak terkontrol menjadi dikontrol”
Jika Anda memberikan value
ke komponen, value
tersebut harus tetap berupa string selama masa pakainya.
Anda tidak dapat mengoper value={undefined}
terlebih dahulu dan kemudian meneruskan value="some string"
karena React tidak akan tahu apakah Anda ingin komponen tidak dikontrol atau dikontrol. Komponen yang dikontrol harus selalu menerima string value
, bukan null
atau undefined
.
Jika value
Anda berasal dari API atau variabel status, nilai tersebut mungkin diinisialisasi ke null
atau undefined
. Dalam hal ini, setel ke string kosong (''
) pada awalnya, atau berikan value={someValue ?? ''}
untuk memastikan value
adalah sebuah string.
Demikian pula, jika Anda mengoper checked
ke checkbox, pastikan itu selalu sebuah boolean.