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. Jika true, React akan memfokuskan elemen ketika terpasang.
  • children: <textarea> tidak menerima children. Untuk Menentukan nilai awal, gunakan defaultValue.
  • cols: Sebuah bilangan. Menentukan lebar bawaaan pada rata-rata lebar karakter. Nilai bawaan adalah 20.
  • disabled: Sebuah boolean. Jika true, input tidak akan menjadi interaktif dan akan terlihat redup.
  • form: Sebuah string. Menentukan id 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 fungsi Event handler . Dibutuhkan untuk area teks terkendali. Beroperasi secara langsung ketika nilai suatu input diubah oleh pengguna (misalkan, beroperasi setiap penekanan tombol). Berperilaku seperti event input pada peramban.
  • onChangeCapture: Sebuah versi onChange yang beroperasi pada fase penangkapan.
  • onInput: Sebuah fungsi Event handler. Beroperasi secara langsung ketika suatu nilai diubah oleh pengguna. Untuk alasan historis, dalam React penggunaan onChange menjadi idiomatik yang berfungsi dengan cara yang serupa.
  • onInputCapture: Sebuah versi onInput yang beroperasi pada fase penangkapan.
  • onInvalid: Sebuah fungsi Event handler. Beroperasi jika sebuah input gagal memvalidasi pada pengiriman formulir. Tidak seperti event bawaan invalid, onInvalid event pada React menggelembung.
  • onInvalidCapture: Sebuah versi onInvalid yang beroperasi pada fase penangkapan.
  • onSelect: Sebuah fungsi Event handler. Beroperasi setelah pemilihan di dalam <textarea> berubah. React memperluas onSelect event untuk juga mengaktifkan pemilihan kosong dan pengeditan (dapat mempengaruhi pemilihan).
  • onSelectCapture: Sebuah versi onSelect yang beroperasi pada fase penangkapan.
  • placeholder: Sebuah string. Ditampilkan dalam warna redup ketika nilai area teks kosong.
  • readOnly: Sebuah boolean. Jika true, area teks tidak dapat diubah oleh pengguna.
  • required: Sebuah boolean. Jika true, nilai harus disediakan agar formulir dapat terkirim.
  • rows: Sebuah bilangan. Menentukan tinggi bawaaan pada rata-rata tinggi karakter. Nilai bawaaan adalah 2.
  • wrap: Nilainya 'hard', 'soft', atau 'off'. Menentukan bagaimana suatu teks akan dibungkus ketika mengirimkan formulir.

Caveats

  • Memberikan children seperti <textarea>something</textarea> tidak diperbolehkan. Gunakan defaultValue 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>
  );
}

Pitfall

Tidak seperti HTML, memberikan teks awal seperti <textarea>Some content</textarea> tidak didukung.


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>
  );
}

Note

Berikan sebuah name kepada <textarea> Anda, misalkan <textarea name="postContent" />. name yang Anda tetapkan akan digunakan sebagai sebuah key di dalam data formulir, misalkan { postContent: "Your post" }.

Pitfall

Secara default, setiap <button> yang berada di dalam sebuah <form> akan mengirimkan data formulir tersebut. Ini bisa mengejutkan! Jika Anda mempunyai kustom komponen React Button Anda sendiri, pertimbangkanlah untuk mengembalikan <button type="button"> daripada <button>. Kemudian, supaya menjadi eksplisit, gunakan <button type="submit"> untuk tombol-tombol yang seharusnya digunakan untuk mengirimkan formulir.


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} />
    </>
  );
}

Pitfall

Jika Anda memberikan value tanpa onChange, mengetik di area teks tersebut akan menjadi mustahil. Jika Anda mengontrol sebuah area teks dengan memberikan beberapa value kepadanya, Anda memaksa area teks tersebut untuk selalu mempunyai nilai yang diberikan. Sehingga jika Anda memberikan sebuah variabel state sebagai sebuah value tetapi lupa untuk memperbarui variabel state tersebut secara sinkronis selama event handler onChange, React akan mengembalikan area teks setelah setiap penekanan tombol ke value yang Anda berikan sebelumnya.


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} />
Console
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 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.