Kami menyajikan kepada Anda terjemahan artikel oleh Chidume Nnamdi, yang diterbitkan di blog.bitsrc.io. Jika Anda ingin mempelajari cara menghindari render yang tidak perlu dan bagaimana alat baru berguna dalam Bereaksi, selamat datang di cat.

Tim React.js bekerja keras untuk membuat React berjalan secepat mungkin. Untuk memungkinkan pengembang mempercepat aplikasi Bereaksi mereka, alat berikut telah ditambahkan ke dalamnya:
- React.lazy dan Suspense untuk keterlambatan memuat komponen;
- Komponen murni
- kait siklus hidup seharusnya memperbarui (...) {...}.
Pada artikel ini, kami akan mempertimbangkan, antara lain, alat pengoptimalan lain yang ditambahkan dalam React v16.6 untuk mempercepat fungsi komponen -
React.memo .
Tip: Gunakan
Bit untuk menginstal dan berbagi komponen Bereaksi. Gunakan komponen Anda untuk membangun aplikasi baru dan membaginya dengan tim untuk mempercepat. Cobalah!

Render ekstra
Dalam Bereaksi, setiap komponen terkait dengan unit tampilan. Komponen juga memiliki status. Ketika nilai status berubah karena tindakan pengguna, komponen menyadari bahwa menggambar ulang diperlukan. Komponen Bereaksi dapat digambar ulang beberapa kali. Dalam beberapa kasus, ini perlu, tetapi paling sering Anda dapat melakukannya tanpa renderer, terutama karena sangat memperlambat aplikasi.
Pertimbangkan komponen berikut:
import React from 'react'; class TestC extends React.Component { constructor(props) { super(props); this.state = { count: 0 } } componentWillUpdate(nextProps, nextState) { console.log('componentWillUpdate') } componentDidUpdate(prevProps, prevState) { console.log('componentDidUpdate') } render() { return ( <div > {this.state.count} <button onClick={()=>this.setState({count: 1})}>Click Me</button> </div> ); } } export default TestC;
Nilai awal dari keadaan {count: 0} adalah 0. Jika Anda mengklik tombol Klik saya, status penghitungan akan menjadi 1. Di layar kami, 0 juga akan berubah menjadi 1. Tetapi jika kami mengklik tombol lagi, masalah mulai: komponen tidak boleh digambar ulang, karena kondisinya belum berubah. Nilai penghitung "ke" adalah 1, nilai baru juga satu, yang berarti bahwa tidak perlu memperbarui DOM.
Untuk melihat pembaruan TestC kami, di mana kondisi yang sama diatur dua kali, saya menambahkan dua metode siklus hidup. React memulai siklus componentWillUpdate ketika komponen diperbarui / digambar ulang karena perubahan status. ComponentdidUpdate React cycle dimulai ketika komponen berhasil dibuat.
Jika kami meluncurkan komponen di browser dan mencoba mengklik tombol Click me beberapa kali, kami mendapatkan hasil berikut:

Mengulangi entri componentWillUpdate di konsol kami menunjukkan bahwa komponen tersebut digambar ulang bahkan ketika keadaan tidak berubah. Ini adalah render tambahan.
Komponen Murni / harusPerbarui komponen
Kait siklus hidup shouldComponentUpdate akan membantu menghindari rendering yang tidak perlu dalam komponen Bereaksi.
React meluncurkan metode
shouldComponentUpdate di awal rendering komponen dan menerima lampu hijau dari metode ini untuk melanjutkan proses atau sinyal bahwa proses
terhambat .
Biarkan shouldComponentUpdate kami terlihat seperti ini:
shouldComponentUpdate(nextProps, nextState) { return true }
nextProps
: nilai properti berikutnya yang akan diterima komponen;nextState
: nilai state
selanjutnya yang akan diterima komponen.
Jadi kami mengizinkan Bereaksi untuk merender komponen karena nilai kembali
true
.
Misalkan kita menulis yang berikut ini:
shouldComponentUpdate(nextProps, nextState) { return false }
Dalam hal ini, kami melarang Bereaksi untuk membuat komponen, karena
false
dikembalikan.
Dari penjelasan di atas, untuk membuat komponen kita perlu mengembalikan
true
. Sekarang kita dapat menulis ulang komponen TestC sebagai berikut:
import React from 'react'; class TestC extends React.Component { constructor(props) { super(props); this.state = { count: 0 } } componentWillUpdate(nextProps, nextState) { console.log('componentWillUpdate') } componentDidUpdate(prevProps, prevState) { console.log('componentDidUpdate') } shouldComponentUpdate(nextProps, nextState) { if (this.state.count === nextState.count) { return false } return true } render() { return ( <div> { this.state.count } <button onClick = { () => this.setState({ count: 1 }) }> Click Me </button> </div> ); } } export default TestC;
Kami menambahkan pengait shouldComponentUpdate ke komponen TestC. Sekarang nilai
count
dalam objek keadaan saat ini
this.state.count
dibandingkan dengan nilai
count
dalam objek keadaan berikutnya
nextState.count
. Jika mereka sama
===
, menggambar ulang tidak terjadi dan
false
dikembalikan. Jika mereka tidak sama,
true
dikembalikan dan penyaji diluncurkan untuk menampilkan nilai baru.
Jika kami menguji kode di browser, kami akan melihat hasil yang familier:

Tetapi dengan mengklik tombol
Click Me
beberapa kali, yang kami lihat adalah yang berikut (hanya ditampilkan sekali!):
componentWillUpdate
componentDidUpdate

Anda dapat mengubah status komponen TestC di tab React DevTools. Klik pada tab React, pilih TestC di sebelah kanan, dan Anda akan melihat nilai status penghitung:

Nilai ini bisa diubah. Klik pada teks penghitung, ketik 2 dan tekan Enter.

Keadaan hitungan akan berubah, dan di konsol kita akan melihat:
componentWillUpdate componentDidUpdate componentWillUpdate componentDidUpdate

Nilai sebelumnya adalah 1, dan yang baru adalah 2, jadi redraw diperlukan.
Mari kita beralih ke
Komponen Murni .
Komponen Murni muncul di Bereaksi dalam versi v15.5. Ini digunakan untuk membandingkan nilai standar (
change detection
). Menggunakan
extend React.PureComponent
, Anda tidak perlu menambahkan metode siklus hidup
shouldComponentUpdate
ke komponen: ubah pelacakan terjadi dengan sendirinya.
Tambahkan PureComponent ke komponen TestC.
import React from 'react'; class TestC extends React.PureComponent { constructor(props) { super(props); this.state = { count: 0 } } componentWillUpdate(nextProps, nextState) { console.log('componentWillUpdate') } componentDidUpdate(prevProps, prevState) { console.log('componentDidUpdate') } render() { return ( <div> { this.state.count } <button onClick = { () => this.setState({ count: 1 }) }> Click Me </button> </div > ); } } export default TestC;
Seperti yang Anda lihat, kami
shouldComponentUpdate
ke dalam komentar. Kami tidak lagi membutuhkannya: semua pekerjaan dilakukan oleh
React.PureComponent
.
Mulai ulang browser untuk menguji solusi baru, dan mengklik tombol
Click Me
beberapa kali, kita dapatkan:


Seperti yang Anda lihat, hanya satu
component*Update
Entri
component*Update
muncul di konsol.
Setelah melihat bagaimana bekerja di Bereaksi dengan menggambar ulang di kelas komponen ES6, kami beralih ke fungsi komponen. Bagaimana cara mencapai hasil yang sama dengan mereka?
Komponen Fungsi
Kita sudah tahu bagaimana mengoptimalkan kerja dengan kelas menggunakan Komponen Murni dan
shouldComponentUpdate
siklus hidup
shouldComponentUpdate
. Tidak ada yang berpendapat bahwa komponen kelas adalah komponen utama Bereaksi, tetapi Anda dapat menggunakan fungsi sebagai komponen.
function TestC(props) { return ( <div> I am a functional component </div> ) }
Penting untuk diingat bahwa komponen fungsi, tidak seperti komponen kelas, tidak memiliki status (meskipun sekarang kait penggunaanState telah
useState
, ini dapat diperdebatkan dengan), yang berarti bahwa kita tidak dapat mengonfigurasi redrawingnya. Metode siklus hidup yang kami gunakan saat bekerja dengan kelas tidak tersedia bagi kami di sini. Jika kita dapat menambahkan kait siklus hidup ke komponen fungsi, kita dapat menambahkan metode
shouldComponentUpdate
untuk memberi tahu Bereaksi bahwa penyaji fungsi diperlukan. (Mungkin, dalam kalimat terakhir, penulis membuat kesalahan faktual. - Approx. Ed.) Dan, tentu saja, kita tidak bisa menggunakan
extend React.PureComponent
.
Kami mengubah kelas komponen kami ES6 TestC menjadi fungsi komponen.
import React from 'react'; const TestC = (props) => { console.log(`Rendering TestC :` props) return ( <div> {props.count} </div> ) } export default TestC;
Setelah rendering di konsol, kita melihat
Rendering TestC :5
.

Buka DevTools dan klik pada tab React. Di sini kita akan mencoba mengubah nilai properti dari komponen TestC. Pilih TestC, dan properti penghitung dengan semua properti dan nilai TestC akan terbuka di sebelah kanan. Kami hanya melihat penghitung dengan nilai saat ini dari 5.
Klik pada angka 5 untuk mengubah nilainya. Jendela input akan muncul sebagai gantinya.

Jika kita mengubah nilai numerik dan menekan Enter, properti komponen akan berubah sesuai dengan nilai yang kita masukkan. Misalkan pada usia 45.

Buka tab Konsol.

Komponen TestC digambar ulang karena nilai sebelumnya dari 5 berubah menjadi yang sekarang - 45. Kembali ke tab Bereaksi dan ubah nilainya menjadi 45, kemudian kembali ke Konsol.

Seperti yang Anda lihat, komponen digambar ulang, meskipun nilai sebelumnya dan yang baru adalah sama. :(
Bagaimana cara mengelola penyaji?
Solusi: React.memo ()
React.memo()
adalah fitur baru yang diperkenalkan di React v16.6. Prinsip operasinya mirip dengan prinsip
React.PureComponent
: membantu dalam mengelola
React.PureComponent
fungsi-komponen.
React.memo(...)
untuk komponen kelas adalah
React.PureComponent
untuk komponen fungsi.
Bagaimana cara kerja dengan React.memo (...)?Cukup sederhana. Katakanlah kita memiliki fungsi komponen.
const Funcomponent = ()=> { return ( <div> Hiya!! I am a Funtional component </div> ) }
Kita hanya perlu meneruskan FuncComponent sebagai argumen ke fungsi React.memo.
const Funcomponent = ()=> { return ( <div> Hiya!! I am a Funtional component </div> ) } const MemodFuncComponent = React.memo(FunComponent)
React.memo mengembalikan MemodFuncComponent yang
purified MemodFuncComponent
. Inilah yang akan kita gambar di markup JSX. Ketika properti dan status komponen berubah, React membandingkan properti dan status komponen sebelumnya dan saat ini. Dan hanya jika mereka tidak identik, fungsi komponen digambar ulang.
Terapkan ini ke komponen fungsi TestC.
let TestC = (props) => { console.log('Rendering TestC :', props) return ( <div> { props.count } </> ) } TestC = React.memo(TestC);
Buka browser dan unduh aplikasi. Buka DevTools dan buka tab React. Pilih
<Memo(TestC)>
.
Jika di blok di sebelah kanan kami mengubah properti penghitung ke 89, aplikasi akan digambar ulang.

Jika kami mengubah nilai ke yang sebelumnya, 89, maka ...

Tidak akan ada penggambaran ulang!
Glory to React.memo (...)! :)
Tanpa menggunakan
React.memo(...)
dalam contoh pertama kami, fungsi komponen TestC digambar ulang bahkan ketika nilai sebelumnya berubah menjadi yang identik. Sekarang, terima kasih kepada
React.memo(...)
, kita dapat menghindari rendering fungsi komponen yang tidak perlu.
Kesimpulan
- Mari kita lihat daftarnya?
React.PureComponent
- perak;React.memo(...)
- emas;React.PureComponent
bekerja dengan kelas ES6;React.memo(...)
berfungsi dengan fungsi;React.PureComponent
mengoptimalkan gambar ulang kelas ES6;React.memo(...)
mengoptimalkan fungsi redrawing;- optimisasi fitur adalah ide yang hebat;
React
tidak akan pernah sama lagi.
Jika Anda memiliki pertanyaan tentang artikel atau informasi tambahan, perubahan atau keberatan, jangan ragu untuk menulis komentar, email, atau pesan pribadi kepada saya.
Terima kasih