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. Jika true, React akan memfokuskan elemen ketika terpasang.
  • children: <textarea> tidak menerima anak (children). Untuk menentukan nilai awal, gunakan defaultValue.
  • cols: Sebuah angka. Menentukan lebar bawaaan pada rata-rata lebar karakter. Nilai bawaan adalah 20.
  • disabled: Sebuah boolean. Jika true, masukan tidak akan menjadi interaktif dan akan terlihat redup.
  • form: Sebuah string. Menentukan id 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 fungsi Event handler . Dibutuhkan untuk area teks terkendali. Beroperasi secara langsung ketika nilai suatu masukan 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 masukan 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 angka. 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

  • Mengoper anak (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 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>
  );
}

Pitfall

Tidak seperti HTML, mengoper 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 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>
  );
}

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

Pitfall

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


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} />
Console
Anda memberikan sebuah prop 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.