<textarea>
Komponen bawaan peramban (browser) <textarea>
yang memungkinkan Anda me-render masukan teks dengan banyak baris (multiline).
<textarea />
Referensi
<textarea>
Untuk menampilkan sebuah area teks, me-render komponen peramban bawaan <textarea>
.
<textarea name="postContent" />
Lihat lebih banyak contoh di bawah
Props
<textarea>
mendukung semua elemen props yang umum.
Anda dapat membuat sebuah area teks yang terkendali (controlled) dengan cara mengoper sebuah prop value
:
value
: Sebuah string. Mengontrol teks di dalam area teks.
Ketika Anda mengoper value
, Anda harus mengoper juga sebuah handler onChange
yang memperbarui nilai yang dioper sebelumnya.
Jika <textarea>
Anda tidak terkendali (uncontrolled), Anda boleh mengoper defaultValue
sebagai gantinya:
defaultValue
: Sebuah string. Menentukan nilai awal untuk sebuah area teks.
<textarea>
props ini relevan baik untuk area text terkendali maupun tidak terkendali:
autoComplete
: Nilainya'on'
atau'off'
. Menentukan perilaku penyelesaian otomatis.autoFocus
: Sebuah boolean. Jikatrue
, React akan memfokuskan elemen ketika terpasang.children
:<textarea>
tidak menerima anak (children). Untuk menentukan nilai awal, gunakandefaultValue
.cols
: Sebuah angka. Menentukan lebar bawaaan pada rata-rata lebar karakter. Nilai bawaan adalah20
.disabled
: Sebuah boolean. Jikatrue
, masukan tidak akan menjadi interaktif dan akan terlihat redup.form
: Sebuah string. Menentukanid
pada suatu<form>
yang memiliki masukan tersebut. Jika dihilangkan, nilainya mengacu pada induk formulir terdekat.maxLength
: Sebuah angka. Menentukan panjang maksimum teks.minLength
: Sebuah angka. Menentukan panjang minimum teks.name
: Sebuah string. Menentukan nama pada masukan yang dikirim dengan formulir tertentu.onChange
: Sebuah fungsiEvent
handler . Dibutuhkan untuk area teks terkendali. Beroperasi secara langsung ketika nilai suatu masukan diubah oleh pengguna (misalkan, beroperasi setiap penekanan tombol). Berperilaku seperti eventinput
pada peramban.onChangeCapture
: Sebuah versionChange
yang beroperasi pada fase penangkapan.onInput
: Sebuah fungsiEvent
handler. Beroperasi secara langsung ketika suatu nilai diubah oleh pengguna. Untuk alasan historis, dalam React penggunaanonChange
menjadi idiomatik yang berfungsi dengan cara yang serupa.onInputCapture
: Sebuah versionInput
yang beroperasi pada fase penangkapan.onInvalid
: Sebuah fungsiEvent
handler. Beroperasi jika sebuah masukan gagal memvalidasi pada pengiriman formulir. Tidak seperti event bawaaninvalid
,onInvalid
event pada React menggelembung.onInvalidCapture
: Sebuah versionInvalid
yang beroperasi pada fase penangkapan.onSelect
: Sebuah fungsiEvent
handler. Beroperasi setelah pemilihan di dalam<textarea>
berubah. React memperluasonSelect
event untuk juga mengaktifkan pemilihan kosong dan pengeditan (dapat mempengaruhi pemilihan).onSelectCapture
: Sebuah versionSelect
yang beroperasi pada fase penangkapan.placeholder
: Sebuah string. Ditampilkan dalam warna redup ketika nilai area teks kosong.readOnly
: Sebuah boolean. Jikatrue
, area teks tidak dapat diubah oleh pengguna.required
: Sebuah boolean. Jikatrue
, nilai harus disediakan agar formulir dapat terkirim.rows
: Sebuah angka. Menentukan tinggi bawaaan pada rata-rata tinggi karakter. Nilai bawaaan adalah2
.wrap
: Nilainya'hard'
,'soft'
, atau'off'
. Menentukan bagaimana suatu teks akan dibungkus ketika mengirimkan formulir.
Caveats
- Mengoper anak (children) seperti
<textarea>something</textarea>
tidak diperbolehkan. GunakandefaultValue
untuk konten awal. - Jika menerima sebuah prop
value
string, sebuah area teks akan dianggap sebagai komponen terkendali. - Sebuah area teks tidak dapat menjadi terkendali dan tidak terkendali secara bersamaan.
- Sebuah area teks tidak dapat beralih menjadi terkendali atau tidak terkendali selama masa pakainya.
- Setiap area teks terkendali membutuhkan sebuah event handler
onChange
yang memperbarui nilai pendukungnya secara sinkron.
Penggunaan
Menampilkan sebuah area teks
Render <textarea>
untuk menampilkan sebuah area teks. Anda dapat menentukan ukuran bawaanya dengan atribut rows
dan cols
, tapi secara bawaan user dapat mengubah ukurannya. Untuk menonaktifkan pengubahan ukuran, Anda dapat menentukan resize: none
di dalam CSS.
export default function NewPost() { return ( <label> Tulis publikasi Anda: <textarea name="postContent" rows={4} cols={40} /> </label> ); }
Menyediakan sebuah label untuk sebuah area teks
Umumnya, Anda akan meletakkan setiap <textarea>
di dalam sebuah tag <label>
. Ini memberitahu suatu peramban apabila label ini berkaitan dengan area teks tertentu. Ketika pengguna mengeklik label tersebut, peramban akan memfokuskan area teks. Hal ini juga diperlukan untuk aksesbilitas: sebuah layar pembaca akan memberitahu keterangan label ketika pengguna memfokuskan area teks tertentu.
Jika Anda tidak dapat menyusun <textarea>
di dalam sebuah <label>
, hubungkanlah mereka dengan mengoper ID yang sama kepada <textarea id>
dan <label htmlFor>
. untuk menghindari konflik antara instances pada satu komponen, buatlah sebuah ID dengan useId
.
import { useId } from 'react'; export default function Form() { const postTextAreaId = useId(); return ( <> <label htmlFor={postTextAreaId}> Tulis publikasi Anda: </label> <textarea id={postTextAreaId} name="postContent" rows={4} cols={40} /> </> ); }
Menyediakan sebuah nilai awal pada sebuah area teks
Anda dapat menentukan nilai awal pada suatu area teks secara opsional. Untuk mengoper nilai awal, gunakan defaultValue
dengan tipe string.
export default function EditPost() { return ( <label> Ubah publikasi anda: <textarea name="postContent" defaultValue="I really enjoyed biking yesterday!" rows={4} cols={40} /> </label> ); }
Membaca nilai area teks ketika mengirimkan sebuah formulir
Tambahkan sebuah <form>
mengelilingi area teks Anda dengan sebuah <button type="submit">
di dalamnya. Tombol itu akan memanggil <form onSubmit>
event handler Anda. Secara default, peramban akan mengirimkan data formulir kepada URL saat ini dan memuat ulang halaman. Anda dapat mengesampingkan perilaku tersebut dengan memanggil e.preventDefault()
. Baca data formulir dengan menggunakan new FormData(e.target)
.
export default function EditPost() { function handleSubmit(e) { // Mencegah peramban dari memuat ulang halaman e.preventDefault(); // Membaca data formulir 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 menggunakannya sebagai objek sederhana: const formJson = Object.fromEntries(formData.entries()); console.log(formJson); } return ( <form method="post" onSubmit={handleSubmit}> <label> Post title: <input name="postTitle" defaultValue="Biking" /> </label> <label> Ubah publikasi Anda: <textarea name="postContent" defaultValue="I really enjoyed biking yesterday!" rows={4} cols={40} /> </label> <hr /> <button type="reset">Atur ulang suntingan</button> <button type="submit">Kirim</button> </form> ); }
Mengendalikan sebuah area teks dengan sebuah variabel state
Sebuah area teks seperti <textarea />
bersifat tak terkendali. Meskipun jika Anda mengoper sebuah nilai awal seperti <textarea defaultValue="Initial text" />
, JSX Anda hanya menetapkan nilai awal, bukan nilai saat ini.
Untuk me-render sebuah teks area terkendali, oper prop value
kepada area teksnya. React akan memaksa area teks tersebut agar selalu mempunyai value
yang Anda berikan. Umumnya, Anda akan mengendalikan sebuah area teks dengan mendeklarasikan sebuah variabel state:
function NewPost() {
const [postContent, setPostContent] = useState(''); // Mendeklarasi sebuah variabel state...
// ...
return (
<textarea
value={postContent} // ...memaksa nilai dari masukan untuk mencocokan variabel state...
onChange={e => setPostContent(e.target.value)} // ... dan memperbarui variabel state di setiap pengeditan!
/>
);
}
Hal ini berguna jika Anda ingin mengulang render di beberapa bagian UI sebagai bentuk tanggapan di setiap penekanan tombol.
import { useState } from 'react'; import MarkdownPreview from './MarkdownPreview.js'; export default function MarkdownEditor() { const [postContent, setPostContent] = useState('_Hello,_ **Markdown**!'); return ( <> <label> Masukkan beberapa markdown: <textarea value={postContent} onChange={e => setPostContent(e.target.value)} /> </label> <hr /> <MarkdownPreview markdown={postContent} /> </> ); }
Penyelesain masalah
Area teks saya tidak memperbarui ketika Saya mengetiknya
Jika Anda me-render sebuah area teks dengan value
tetapi tanpa onChange
, Anda akan melihat sebuah error di konsol:
// 🔴 Bug: area teks terkendali tanpa handler onChange
<textarea value={something} />
value
ke sebuah field formulir tanpa sebuah handler onChange
. area teksnya akan ter-render menjadi sebuah field yang hanya untuk dibaca. Jika field-nya harus mutable, gunakan defaultValue
. Selain itu, berikan onChange
atau readOnly
.Seperti yang disarankan pada pesan error berikut, jika Anda hanya ingin menentukan nilai awal, oper defaultValue
sebagai gantinya:
// ✅ Good: area teks tidak terkendali dengan sebuah nilai awal
<textarea defaultValue={something} />
Jika Anda ingin mengendalikan area teks ini dengan sebuah variabel state, Tentukanlah sebuah handler onChange
:
// ✅ Good: area teks terkendali dengan onChange
<textarea value={something} onChange={e => setSomething(e.target.value)} />
Jika nilainya sengaja diatur hanya untuk dibaca, tambahkan sebuah prop readOnly
untuk menghilangkan error:
// ✅ Good: area teks terkontrol yang hanya untuk dibaca tanpa onChange
<textarea value={something} readOnly={true} />
Tanda sisipan saya melompat ke awal pada setiap penekanan tombol
Jika Anda mengendalikan sebuah area teks, Anda harus memperbarui variabel state-nya ke nilai area teksnya melalui DOM selama onChange
.
Anda tidak dapat memperbarui nilainya dengan sesuatu selain e.target.value
:
function handleChange(e) {
// 🔴 Bug: memperbarui sebuah masukan dengan sesuatu selain e.target.value
setFirstName(e.target.value.toUpperCase());
}
Anda juga tidak dapat memperbaruinya secara asinkron:
function handleChange(e) {
// 🔴 Bug: memperbarui sebuah masukan secara asinkron
setTimeout(() => {
setFirstName(e.target.value);
}, 100);
}
Untuk memperbaiki kode Anda, perbarui secara sinkron ke e.target.value
:
function handleChange(e) {
// ✅ Memperbarui sebuah masukan terkendali ke e.target.value secara sinkron
setFirstName(e.target.value);
}
Jika ini tidak menyelesaikan masalah, ada kemungkinan area teks terhapus dan ditambahkan kembali dari DOM di setiap penekanan tombol. Ini dapat terjadi jika Anda secara tidak sengaja menyetel ulang state di setiap render ulang. Misalkan, ini dapat terjadi jika area teksnya atau salah satu dari parents-nya selalu menerima sebuah atribut key
yang berbeda, atau jika Anda menyusun definisi komponen (dimana hal ini tidak diizinkan React dan menyebabkan komponen “dalam” ter-mount ulang di setiap render).
Saya menerima sebuah error: “Sebuah komponen sedang mengubah masukan yang tidak terkendali menjadi terkendali”
Jika Anda memberikan sebuah value
ke komponen, nilai tersebut harus tetap berupa string selama masa pakainya.
Anda tidak dapat mengoper value={undefined}
terlebih dahulu dan kemudian oper value="some string"
karena React tidak akan mengetahui apakah anda ingin komponennya menjadi tidak terkontrol atau terkontrol. Sebuah controlled component harus selalu menerima sebuah string value
, bukan null
atau undefined
.
Jika value
Anda berasal dari sebuah API atau sebuah variabel state, nilai tersebut mungkin diinisiasi ke null
atau undefined
. Dalam hal ini, Berikan sebuah string kosong (''
) pada awalnya, atau oper value={someValue ?? ''}
untuk memastikan value
-nya adalah string.