Komponen yang terkontrol dan tidak terkendali dalam Bereaksi tidak harus rumit

Halo, Habr! Saya mempersembahkan kepada Anda terjemahan artikel "Input formulir yang terkontrol dan tidak terkendali dalam Bereaksi tidak harus rumit" oleh Gosha Arinich.

Anda mungkin telah melihat banyak artikel yang mengatakan, "Anda tidak boleh menggunakan" setState ", sedangkan dokumen mengklaim bahwa" referensi buruk. "Ini semua sangat kontradiktif. Kadang-kadang, sulit untuk mencari cara untuk memperbaikinya, dan apa kriteria untuk memilih antara metode ini.

Jadi bagaimana Anda membuat bentuk-bentuk? Setelah semua, bentuk adalah pusat untuk banyak aplikasi web. Namun, pengolahan bentuk di Bereaksi adalah batu penjuru, bukan?

Namun, itu tidak sangat keras Mari saya tunjukkan perbedaan antara pendekatan ini, serta kapan Anda harus menggunakan masing-masing pendekatan tersebut.

Komponen yang tidak dikelola


Komponen yang tidak dikelola seperti bentuk HTML biasa:

class Form extends Component {
  render() {
    return (
      <div>
        <input type="text" />
      </div>
    );
  }
}

Mereka mengingat semua yang Anda ketikkan. Maka Anda bisa mendapatkan nilainya menggunakan referensi. Misalnya, di penangan onClick:


class Form extends Component {
  handleSubmitClick = () => {
    const name = this._name.value;
    // do something with `name`
  }
  render() {
    return (
      <div>
        <input type="text" ref={input => this._name = input} />
        <button onClick={this.handleSubmitClick}>Sign up</button>
      </div>
    );
  }
}

Dengan kata lain, Anda perlu "menarik" nilai dari bidang saat Anda membutuhkannya. Ini dapat dilakukan saat mengirimkan formulir.

Ini adalah cara termudah untuk mengimplementasikan formulir. Tentu saja, harus ada alasan yang baik untuk menggunakannya, yaitu: bentuk yang paling sederhana, baik selama studi Bereaksi.
Namun, metode ini tidak begitu fleksibel, jadi mari kita lihat lebih baik komponen yang dikelola.

Komponen yang Dikelola:


Komponen yang dikelola menerima nilai saat ini sebagai alat peraga, serta panggilan balik untuk mengubah nilai ini. Anda dapat mengatakan bahwa ini adalah cara yang lebih "reaktif" untuk mengontrol komponen, namun ini tidak berarti Anda harus selalu menggunakan metode ini.

<input value={someValue} onChange={handleChange} />

Ini semua sangat baik, tetapi nilai formulir input harus ada di beberapa negara. Biasanya, komponen yang merender formulir input (mis. Formulir) menyimpannya dalam keadaan:


class Form extends Component {
  constructor() {
    super();
    this.state = {
      name: '',
    };
  }

  handleNameChange = (event) => {
    this.setState({ name: event.target.value });
  };

  render() {
    return (
      <div>
        <input
          type="text"
          value={this.state.name}
          onChange={this.handleNameChange}
        />
      </div>
    );
  }
}

(Tentu saja, itu bisa dalam keadaan komponen lain atau bahkan di toko keadaan terpisah, misalnya, Redux).

Setiap kali Anda memasukkan karakter baru, handleNameChange dipanggil. Dibutuhkan nilai baru dari formulir input dan menulisnya untuk menyatakan.

gambar

  • Semuanya dimulai dengan baris kosong - '';
  • Anda memasukkan huruf 'a' dan handleNameChange mendapatkannya dan memanggil setState. Kemudian formulir input diberikan lagi dengan nilai 'a';
  • Anda memasukkan huruf 'b' dan handleNameChange mendapatkan nilai 'ab' dan menetapkannya untuk menyatakan. Formulir input Opet diberikan, tetapi sekarang dengan nilai 'ab'.

Aliran ini tampaknya "mendorong" perubahan ke dalam formulir, itulah sebabnya komponen selalu memiliki nilai saat ini dari data input, tanpa memerlukan permintaan pembaruan eksplisit.

Ini berarti bahwa data Anda (negara bagian) dan antarmuka pengguna (formulir input) selalu sinkron. Negara memberi nilai pada formulir, sementara formulir mengubah nilai keadaan saat ini.

Ini juga berarti bahwa formulir dapat segera menanggapi perubahan, yang pada gilirannya diperlukan untuk:

  • umpan balik cepat, seperti validasi;
  • nonaktifkan tombol tertentu sampai semua bidang formulir valid;
  • memungkinkan pemrosesan format bidang input tertentu, seperti nomor kartu kredit.

Tetapi jika Anda tidak membutuhkannya dan Anda berpikir bahwa komponen yang tidak dikelola lebih sederhana, maka gunakanlah.

Apa yang membuat komponen “dapat dikelola”?


Tentu saja, ada elemen bentuk lain, seperti: kotak centang, radio, textarea dan pilih.
Sebuah komponen menjadi dapat dikelola ketika Anda menyetel nilainya menggunakan properti. Itu saja.

Namun, masing-masing elemen formulir memiliki cara yang berbeda untuk menetapkan nilai, jadi di sini adalah tabel kecil untuk pemahaman umum:

ElemenNilaiPanggilan balik untuk perubahanNilai baru dalam panggilan balik
<input type="text" />
value = "string"dalam perubahanevent.target.value
<input type="checkbox" />
checked = {boolean}dalam perubahanevent.target.checked
<input type="radio" />
checked = {boolean}dalam perubahanevent.target.checked
<textarea />
value = "string"dalam perubahanevent.target.value
<select />
value = "nilai opsi"dalam perubahanevent.target.value

temuan


Komponen yang dikelola dan tidak dikelola memiliki kelebihan dan kekurangan. Mengevaluasi situasi tertentu dan memilih pendekatan - jika ini cocok untuk Anda, lalu mengapa tidak memanfaatkannya?

Jika formulir Anda sangat sederhana dalam hal berinteraksi dengan antarmuka pengguna, maka komponen yang tidak dikelola sempurna untuk Anda. Anda tidak harus mendengarkan apa yang dikatakan berbagai artikel buruk.

gambar

Selain itu, memilih jenis komponen bukanlah keputusan yang dibuat sekali dan untuk semua: Anda selalu dapat mengganti komponen yang tidak dikelola dengan yang dikelola. Transisi dari satu ke yang lain tidak begitu sulit.

All Articles