Ada tiga jawaban di sini, tergantung pada versi Bereaksi Anda (dipaksa) bekerja, dan apakah Anda ingin menggunakan kait.
Hal pertama yang pertama:
Sangat penting untuk memahami bagaimana React bekerja, sehingga Anda dapat melakukan hal-hal dengan benar (protip: itu sangat layak dijalankan melalui latihan tutorial Bereaksi di situs web React. Ini ditulis dengan baik, dan mencakup semua dasar-dasar dengan cara yang benar-benar menjelaskan cara melakukan sesuatu). "Benar" di sini berarti Anda sedang menulis antarmuka aplikasi yang akan dirender di browser; semua pekerjaan antarmuka terjadi di Bereaksi, bukan di "apa yang Anda terbiasa jika Anda sedang menulis halaman web" (inilah sebabnya React apps adalah "apps", bukan "halaman web").
Aplikasi Bereaksi dibuat berdasarkan dua hal:
- properti komponen sebagaimana dideklarasikan oleh orang tua mana pun yang membuat turunan dari komponen itu, yang orang tua dapat memodifikasi sepanjang siklus hidupnya, dan
- keadaan internal komponen itu sendiri, yang dapat dimodifikasi sendiri sepanjang siklus hidupnya sendiri.
Apa yang Anda jelas tidak lakukan ketika Anda menggunakan Bereaksi menghasilkan elemen HTML dan kemudian menggunakannya: ketika Anda mengatakan Bereaksi untuk menggunakan <input>
, misalnya, Anda tidak membuat elemen input HTML, Anda mengatakan Bereaksi untuk membuat objek input Bereaksi yang terjadi untuk merender sebagai elemen input HTML, dan yang penanganan eventnya melihat, tetapi tidak dikendalikan oleh , event input elemen HTML.
Saat menggunakan Bereaksi, apa yang Anda lakukan adalah membuat elemen UI aplikasi yang menyajikan data (seringkali dapat dimanipulasi) kepada pengguna, dengan interaksi pengguna mengubah status Komponen, yang dapat menyebabkan rerender bagian dari antarmuka aplikasi Anda untuk mencerminkan keadaan baru. Dalam model ini, negara selalu menjadi otoritas terakhir, bukan "perpustakaan UI apa pun yang digunakan untuk membuatnya", yang di web adalah DOM peramban. DOM hampir merupakan renungan dalam model pemrograman ini: itu hanya kerangka UI tertentu yang Bereaksi kebetulan gunakan.
Jadi dalam kasus elemen input, logikanya adalah:
- Anda mengetikkan elemen input,
- tidak ada yang terjadi pada elemen input Anda, peristiwa itu dicegat oleh Bereaksi dan langsung dibunuh ,
- Bereaksi maju acara ke fungsi yang telah Anda atur untuk penanganan acara,
- fungsi yang dapat menjadwalkan pembaruan negara,
- jika ya, React menjalankan pembaruan status itu (tidak sinkron!) dan akan memicu
render
panggilan setelah pembaruan, tetapi hanya jika pembaruan status mengubah status.
- hanya setelah render ini terjadi, UI akan menunjukkan bahwa Anda "mengetik huruf".
Semua itu terjadi dalam hitungan milidetik, jika tidak kurang, jadi sepertinya Anda mengetik ke elemen input dengan cara yang sama seperti "dari hanya menggunakan elemen input pada halaman", tapi itu sama sekali bukan itu terjadi.
Jadi, dengan itu, pada cara mendapatkan nilai dari elemen dalam Bereaksi:
Bereaksi 15 dan di bawah, dengan ES5
Untuk melakukan sesuatu dengan benar, komponen Anda memiliki nilai status, yang ditampilkan melalui bidang input, dan kami dapat memperbaruinya dengan membuat elemen UI mengirim perubahan acara kembali ke komponen:
var Component = React.createClass({
getInitialState: function() {
return {
inputValue: ''
};
},
render: function() {
return (
//...
<input value={this.state.inputValue} onChange={this.updateInputValue}/>
//...
);
},
updateInputValue: function(evt) {
this.setState({
inputValue: evt.target.value
});
}
});
Jadi, kami memberi tahu React untuk menggunakan updateInputValue
fungsi untuk menangani interaksi pengguna, gunakan setState
untuk menjadwalkan pembaruan status, dan fakta yang render
mengetuk ke dalam this.state.inputValue
berarti bahwa ketika ia merender setelah memperbarui status, pengguna akan melihat teks pembaruan berdasarkan pada apa yang mereka ketik.
tambahan berdasarkan komentar
Mengingat bahwa input UI mewakili nilai status (pertimbangkan apa yang terjadi jika pengguna menutup tab di tengah jalan, dan tab dikembalikan. Apakah semua nilai yang diisi harus dipulihkan? Jika demikian, itu adalah keadaan). Itu mungkin membuat Anda merasa seperti formulir besar membutuhkan puluhan atau bahkan seratus formulir input, tetapi Bereaksi adalah tentang memodelkan UI Anda dengan cara yang dapat dipertahankan: Anda tidak memiliki 100 bidang input independen, Anda memiliki grup input terkait, sehingga Anda menangkap masing-masing grup dalam komponen dan kemudian membangun formulir "master" Anda sebagai kumpulan grup.
MyForm:
render:
<PersonalData/>
<AppPreferences/>
<ThirdParty/>
...
Ini juga lebih mudah dirawat daripada komponen bentuk tunggal raksasa. Membagi kelompok menjadi Komponen dengan pemeliharaan negara, di mana setiap komponen hanya bertanggung jawab untuk melacak beberapa bidang input sekaligus.
Anda juga mungkin merasa "repot" untuk menulis semua kode itu, tetapi itu adalah penghematan yang salah: pengembang-yang-bukan-Anda, termasuk Anda di masa depan, sebenarnya sangat diuntungkan dengan melihat semua input tersebut dihubungkan secara eksplisit, karena itu membuat jalur kode lebih mudah dilacak. Namun, Anda selalu dapat mengoptimalkan. Misalnya, Anda dapat menulis tautan negara
MyComponent = React.createClass({
getInitialState() {
return {
firstName: this.props.firstName || "",
lastName: this.props.lastName || ""
...: ...
...
}
},
componentWillMount() {
Object.keys(this.state).forEach(n => {
let fn = n + 'Changed';
this[fn] = evt => {
let update = {};
update[n] = evt.target.value;
this.setState(update);
});
});
},
render: function() {
return Object.keys(this.state).map(n => {
<input
key={n}
type="text"
value={this.state[n]}
onChange={this[n + 'Changed']}/>
});
}
});
Tentu saja, ada versi yang disempurnakan dari ini, jadi kunjungi https://npmjs.com dan cari solusi menghubungkan kondisi React yang paling Anda sukai. Open Source kebanyakan tentang menemukan apa yang telah dilakukan orang lain, dan menggunakannya daripada menulis sendiri semuanya dari awal.
Bereaksi 16 (dan 15,5 transisi) dan JS 'modern'
Pada React 16 (dan soft-starting dengan 15.5) createClass
panggilan tidak lagi didukung, dan sintaksis kelas perlu digunakan. Ini mengubah dua hal: sintaksis kelas yang jelas, tetapi juga this
pengikatan konteks yang createClass
dapat melakukan "gratis", jadi untuk memastikan semuanya tetap berfungsi, pastikan Anda menggunakan notasi "panah gemuk" untuk this
konteks mempertahankan fungsi anonim di onWhatever
penangan, seperti yang onChange
kita digunakan dalam kode di sini:
class MyComponent extends React.Component {
constructor(props) {
super(props);
this.state = {
inputValue: ''
};
}
render() {
return (
//...
<input value={this.state.inputValue} onChange={evt => this.updateInputValue(evt)}/>
//...
);
},
updateInputValue(evt) {
this.setState({
inputValue: evt.target.value
});
}
});
Anda mungkin juga pernah melihat orang menggunakan bind
konstruktor mereka untuk semua fungsi penanganan acara mereka, seperti ini:
constructor(props) {
super(props);
this.handler = this.handler.bind(this);
...
}
render() {
return (
...
<element onclick={this.handler}/>
...
);
}
Jangan lakukan itu.
Hampir setiap saat Anda menggunakan bind
, pepatah "Anda salah melakukannya" berlaku. Kelas Anda sudah mendefinisikan prototipe objek, dan sudah mendefinisikan konteks instance. Jangan menempatkan bind
di atas itu; gunakan penerusan kejadian normal alih-alih menduplikasi semua panggilan fungsi Anda di konstruktor, karena duplikasi itu meningkatkan permukaan bug Anda, dan membuatnya lebih sulit untuk melacak kesalahan karena masalahnya mungkin ada di konstruktor Anda alih-alih di mana Anda memanggil kode Anda. Serta menempatkan beban pemeliharaan pada orang lain yang Anda (miliki atau pilih) untuk bekerja dengannya.
Ya, saya tahu dokumen reaksi mengatakan tidak apa-apa. Bukan, jangan lakukan itu.
Bereaksi 16.8, menggunakan komponen fungsi dengan kait
Pada Bereaksi 16.8 komponen fungsi (yaitu secara harfiah hanya fungsi yang mengambil props
argumen sebagai dapat digunakan seolah-olah itu adalah instance dari kelas komponen, tanpa pernah menulis kelas) juga dapat diberi status, melalui penggunaan kait .
Jika Anda tidak memerlukan kode kelas penuh, dan fungsi instance tunggal akan dilakukan, maka Anda sekarang dapat menggunakan useState
hook untuk mendapatkan sendiri variabel status tunggal, dan fungsi pembaruannya, yang bekerja kira-kira sama dengan contoh di atas, kecuali tanpa yang setState
fungsi panggilan:
import { useState } from 'react';
function myFunctionalComponentFunction() {
const [input, setInput] = useState(''); // '' is the initial state value
return (
<div>
<label>Please specify:</label>
<input value={input} onInput={e => setInput(e.target.value)}/>
</div>
);
}
Sebelumnya perbedaan tidak resmi antara kelas dan komponen fungsi adalah "komponen fungsi tidak memiliki status", jadi kita tidak dapat menyembunyikannya lagi: perbedaan antara komponen fungsi dan komponen kelas dapat ditemukan tersebar di beberapa halaman dengan sangat baik -dokumen reaksi tertulis (tidak ada jalan pintas penjelasan satu liner untuk dengan mudah disalahartikan untuk Anda!) yang harus Anda baca sehingga Anda tahu apa yang Anda lakukan dan dengan demikian dapat mengetahui apakah Anda memilih yang terbaik (apa pun artinya bagi Anda) solusi untuk memprogram diri Anda sendiri karena masalah yang Anda alami.
this.onSubmit.bind(this);