<textarea>
komponen bawaan peramban <textarea>
yang memungkinkan Anda render teks input dengan banyak baris.
<textarea />
Referensi
<textarea>
Untuk menampilkan sebuah area teks, render komponen bawaan peramban <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 dengan cara memberikan sebuah prop value
:
value
: Sebuah string. Mengontrol teks di dalam area teks.
Ketika Anda memberikan value
, Kamu harus memberikan juga sebuah onChange
handler yang memperbarui nilai yang diberikan sebelumnya.
Jika <textarea>
Anda tidak terkendali, Anda boleh memberikan 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 children. Untuk Menentukan nilai awal, gunakandefaultValue
.cols
: Sebuah bilangan. Menentukan lebar bawaaan pada rata-rata lebar karakter. Nilai bawaan adalah20
.disabled
: Sebuah boolean. Jikatrue
, input tidak akan menjadi interaktif dan akan terlihat redup.form
: Sebuah string. Menentukanid
pada suatu<form>
yang memiliki input tersebut. Jika dihilangkan, nilainya mengacu pada induk formulir terdekat.maxLength
: Sebuah bilangan. Menentukan panjang maksimum teks.minLength
: Sebuah bilangan. Menentukan panjang minimum teks.name
: Sebuah string. Menentukan nama pada input yang dikirim dengan formulir tertentu.onChange
: Sebuah fungsiEvent
handler . Dibutuhkan untuk area teks terkendali. Beroperasi secara langsung ketika nilai suatu input 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 input 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 bilangan. 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
- Memberikan 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 sinkronis.
Penggunaan
Menampilkan sebua area teks
Render <textarea>
untuk menampilkan sebuah area teks. Kamu dapat menentukan ukuran bawaanya dengan atribut rows
dan cols
, tapi secara bawaan user dapat mengubah ukurannya. Untuk menonaktifkan pengubahan ukuran, kamu 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 meletakkan <textarea>
di dalam sebuah <label>
, hubungkanlah mereka dengan memberikan 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
Kamu dapat menentukan nilai awal pada suatu area teks secara opsional. Untuk memberikan 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 mengirimakn *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 memberikan sebuah nilai awal seperti <textarea defaultValue="Initial text" />
, JSX Anda hanya menetapkan nilai awal, bukan nilai saat ini.
Untuk render sebuah teks area terkendali, berikan prop value
kepada area teksnya. React akan memaksa area teks tersebut agar selalu mempunyai value
yang Anda berikan. Umumnya, kamu 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 input 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} /> </> ); }
Troubleshooting
My text area doesn’t update when I type into it
If you render a text area with value
but no onChange
, you will see an error in the console:
// 🔴 Bug: controlled text area with no onChange handler
<textarea 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 text area with an initial value
<textarea defaultValue={something} />
If you want to control this text area with a state variable, specify an onChange
handler:
// ✅ Good: controlled text area with onChange
<textarea 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 text area without on change
<textarea value={something} readOnly={true} />
My text area caret jumps to the beginning on every keystroke
If you control a text area, you must update its state variable to the text area’s value from the DOM during onChange
.
You can’t update it to something other than e.target.value
:
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 text area 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, this can happen if the text area or one of its parents always receives a different key
attribute, or if you nest component definitions (which is not allowed in React and causes the “inner” component to remount on every render).
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 a string.