React.js Lihat Tutorial Manajemen Status
Diterbitkan: 2022-03-11Salah satu masalah terbesar dan paling umum dalam pengembangan web front-end adalah manajemen negara. Pengembang front-end lepas seperti saya terus-menerus fokus untuk menjaga objek negara tetap sinkron dengan tampilannya dan representasi DOM. Pengguna dapat berinteraksi dengan aplikasi dalam banyak cara dan merupakan tugas besar untuk menyediakan transisi yang bersih dari satu keadaan ke keadaan lainnya.
Sedikit sejarah
Belum lama ini, aplikasi web memiliki aliran data yang lebih sederhana. Browser akan mengirim permintaan ke server, semua logika aplikasi akan dieksekusi di server, dan tampilan HTML penuh akan dikirim kembali ke browser untuk dipresentasikan kepada pengguna. Tindakan pengguna berikutnya (seperti klik, pengiriman formulir, dll.) akan memicu alur yang sama lagi. Aplikasi tidak perlu khawatir tentang status pengguna dan setiap tampilan dapat dibuat ulang dengan mengirimkan permintaan baru ke server.
Namun, aplikasi web tumbuh dalam kompleksitasnya dan tuntutan pengguna terhadap UI/UX juga meningkat. Memuat ulang seluruh halaman, ketika hanya satu bagian yang berubah, tidak efektif dan lambat. Kami membutuhkan interaksi yang cepat, cepat, dan responsif dengan dampak langsung pada UI.
JavaScript datang untuk menyelamatkan. Pengembang mulai menulis sejumlah besar kode yang dieksekusi di browser sebelum permintaan dikirim ke server. jQuery juga membawa kemajuan signifikan untuk pengembangan web front-end, karena menyediakan kemampuan out-of-the-box yang sederhana dan efektif seperti validasi sisi klien, modal windows, pesan peringatan, animasi, dan bahkan pembaruan halaman parsial berbasis Ajax.
Memahami Kompleksitas
Mari kita lihat contoh sederhana mengevaluasi kekuatan kata sandi. Jika kata sandinya OK, kotak input harus memiliki batas hijau dan akan menampilkan pesan yang bagus. Jika kata sandi lemah, kotak input harus memiliki batas merah dan akan menampilkan pesan peringatan. Kami mungkin juga menunjukkan wajah tersenyum ketika kata sandi cukup kuat.
Kode berikut menunjukkan bagaimana hal ini dapat dilakukan dengan manipulasi DOM. Ada banyak "jika" di sini, dan kodenya tidak terlalu mudah dibaca.
if (hasInputBorder()) { removeInputBorder(); } if (text.length === 0) { if (hasMessage()) { removeMessage(); } if (hasSmiley()) { removeSmiley(); } } else { var strength = getPasswordStrength(text); if (!hasInputBorder()) { addInputBorder(); } var color = (strength == 'weak' ? 'red' : 'green'); setInputBorderColor(color); var message = (strength == 'weak' ? "Password is weak" : "That's what I call a password!"); if (hasMessage()) { setMessageText(message); } else { addMessageWithText(message); } if (strength == 'weak') { if (hasSmiley()) { removeSmiley(); } } else { if (!hasSmiley()) { addSmiley(); } } }
Seperti yang ditunjukkan di atas, pertama-tama kita perlu memeriksa apakah pengguna memberikan kata sandi sama sekali dan menangani kasus di mana bidang kata sandi kosong. Dan dalam semua kasus, kita perlu memastikan bahwa semua elemen DOM terkait diperbarui dengan benar. Ini termasuk pesan, perbatasan, dan wajah tersenyum.
Bidang kata sandi kami dapat berada di salah satu dari tiga status: kosong, lemah, atau kuat. Dan seperti yang dicatat, kami memiliki tiga elemen DOM berbeda yang dipengaruhi oleh status bidang kata sandi. Menangani semua kombinasi, dan memastikan bahwa tampilan kita ditampilkan dengan benar, meningkatkan kompleksitas siklomatik bahkan untuk sepotong kode sederhana seperti ini.
DOM bekerja dalam mode dipertahankan , yang berarti hanya mengingat status saat ini. Untuk mengubah tampilan kita, kita perlu memberikan instruksi untuk setiap elemen DOM dan memprogram transisi.
Transisi pengkodean alih-alih status bisa rumit. Jumlah cabang dan pemeriksaan yang perlu kita lakukan dalam kode kita tumbuh secara eksponensial dengan jumlah status tampilan yang harus dikelola.
Dalam contoh kami, kami mendefinisikan tiga status tampilan, yang memberi kami 3 * 2 = 6
transisi. Secara umum, dengan N keadaan, kita memiliki N * (N - 1) = N^2 - N
transisi yang perlu kita modelkan. Pikirkan saja tentang peningkatan kompleksitas jika kita menambahkan status keempat ke contoh kita.
Biasanya ada terlalu banyak kode yang terkait dengan pemodelan transisi . Akan jauh lebih baik jika kita dapat mendefinisikan status tampilan dan tidak mengkhawatirkan semua detail transisi dari satu status ke status lainnya.
Mengurangi Kompleksitas
Dengan asumsi bahwa kita dapat mendeklarasikan status tampilan berdasarkan status model, alih-alih mengkodekan transisi secara eksplisit dari satu status ke status lainnya, kita dapat memiliki sesuatu seperti ini:
var strength = getPasswordStrength(text); if (text.length == 0) { return div(input({type: 'password', value: text})); } else if (strength == 'weak') { return div( input({type: 'password', value: text, borderColor: 'red'}), span({}, "Weak") ); } else { return div( input({type: 'password', value: text, borderColor: 'green'}), span({}, "That's what I call a password!"), img({class: 'icon-smiley'}) ); }
Di sini kami memiliki tiga cabang kode sederhana, yang mewakili tiga kemungkinan status aplikasi kami. Kami hanya mengembalikan spesifikasi tampilan di setiap cabang, tergantung pada status model. Semua kode manipulasi DOM dihapus; kami hanya memberikan informasi tentang apa yang kami inginkan, dan bukan bagaimana menuju ke sana.
Meskipun pendekatan ini mengurangi kompleksitas kode secara signifikan, pendekatan ini juga mengasumsikan ada seseorang atau sesuatu yang lain untuk menangani manipulasi DOM yang sebenarnya atas nama kami.
Di sinilah React masuk. React akan memastikan bahwa status tampilan segera dikelola dan diperbarui berdasarkan status model data yang mendasarinya.
Reaksi
React adalah library JavaScript yang dibuat oleh Facebook. Ini dirancang untuk menangani bagian UI dari aplikasi web. Anda dapat menganggapnya sebagai V dalam arsitektur MVC. Hal ini sangat terfokus. Itu tidak membuat asumsi tentang sisa tumpukan teknologi Anda dan tidak menangani apa pun selain komponen rendering. Itu tidak menyediakan mekanisme perutean, model, atau fitur lain yang biasanya dibundel dalam kerangka kerja yang lebih besar. Dengan demikian, Anda dapat mencampurnya dan menggunakannya dengan pustaka atau kerangka kerja lain yang Anda inginkan.
React memungkinkan kita untuk mendefinisikan UI sebagai pohon komponen komposit. Pengembang React mendefinisikan komponen-komponen tersebut dengan menentukan fungsi render yang menjelaskan komponen, dengan status input. Fungsi itu harus murni (yaitu, tidak boleh memiliki efek samping atau bergantung pada apa pun selain input eksplisitnya).
Fungsi render mengembalikan deskripsi tampilan, yang disebut React sebagai DOM Virtual . Anggap saja sebagai objek JavaScript yang sesuai dengan elemen DOM yang dirender.
Saat Anda mengubah status komponen, itu hanya merender ulang dirinya sendiri dan semua elemen turunannya, mengembalikan Virtual DOM baru.
Selain itu, React tidak akan melakukan penggantian HTML sederhana, saat transisi dari satu status ke status lainnya. Ini akan menemukan perbedaan antara status sebelumnya dan status baru, dan menghitung rangkaian operasi DOM yang paling efektif untuk menjalankan transisi.
Bahkan tanpa mempertimbangkan kinerja, pengurangan kompleksitas kode itu sendiri signifikan dan memungkinkan kami untuk memfokuskan upaya kami pada bagian yang lebih unik dan kompleks dari aplikasi kami.
Untuk mendapatkan sedikit lebih konkret, ini adalah bagaimana contoh tutorial kami akan dibuat menggunakan React untuk mengelola status tampilan.
CATATAN: Contoh kode berikut ditulis dalam praprosesor JSX, yang merupakan cara umum untuk menulis UI berbasis React.
function getPasswordStrength(text) { // Some code that calculates the strength given the password text. } var PasswordWithStrength = React.createClass({ getInitialState: function() { return {value: ''}; }, render: function() { var strength = getPasswordStrength(this.state.value); if (this.state.value.length == 0) { return <div> <input type="password" value={this.state.value} onChange={this.handleInputChange} /> </div>; } else if (strength == 'weak') { return <div> <input type="password" value={this.state.value} onChange={this.handleInputChange} style={ {border: '1px solid red'} } /> <span style={{color: 'red'}}>Weak!</span> </div>; } else { return <div> <input type="password" value={this.state.value} onChange={this.handleInputChange} style={ {border: '1px solid green'} } /> <span style={{color: 'green'}}>That's what I call a password!</span> <Emoji value="smiley" /> </div>; } }, handleInputChange: function(ev) { this.setState({value: ev.target.value}); } }); React.render(<PasswordWithStrength />, document.body);
Komponen Emoji
yang dirender saat kekuatan kata sandi OK dengan <Emoji value="smiley" />
hanyalah komponen khusus lainnya (seperti PasswordWithStrength
). Ini didefinisikan seperti ini:

var Emoji = React.createClass({ render: function() { var emojiSrc = this.props.value + '.png'; return <img src={emojiSrc}></img>; } });
React.js vs. Lainnya
Namun, dalam keadilan, ada kerangka kerja JavaScript sisi klien lainnya (seperti Ember, Angular, Knockout, dan lainnya) yang memecahkan masalah manajemen status tampilan juga, dan bahkan menambahkan lebih banyak fitur ke dalamnya. Jadi, mengapa Anda ingin menggunakan React daripada framework lain?
Ada dua keunggulan utama yang dimiliki React, dibandingkan dengan sebagian besar perpustakaan lainnya.
Tidak Ada Pengikatan Data
Beberapa kerangka kerja alternatif lainnya menggunakan pengikatan data untuk memetakan elemen DOM ke properti status, dan menjaganya tetap sinkron dengan mengamati perubahan properti. Pendekatan ini memungkinkan rendering tampilan sekali, dengan setiap perubahan kemudian hanya memicu modifikasi elemen DOM yang terpengaruh. Alternatif lain menggunakan pemeriksaan kotor ; yaitu, alih-alih mengamati perubahan properti individu, mereka hanya melakukan perbedaan antara status sebelumnya dan yang baru. React lebih mirip dengan pendekatan yang terakhir tetapi, alih-alih membandingkan status, ini membandingkan representasi tampilan.
React tidak memiliki pengikatan data. Pengembang diharapkan memanggil metode setState
, atau merender ulang komponen teratas, saat status diubah. Ini mencakup aliran satu arah, dari keadaan ke tampilan.
Konsep ini mudah diadopsi karena pengembang umumnya tidak memikirkan pengikatan data. Fokusnya adalah pada representasi visual dari data. Oleh karena itu Anda tidak perlu memikirkan properti dependen, pemformatan, pengikatan tag HTML khusus, dll. Dengan React, Anda cukup merender ulang komponen saat model berubah.
Untuk memahami perbedaan dalam manajemen status tampilan di sini, mari kita bandingkan Ember dan React . Kami akan membuat objek person
yang akan menampilkan nama lengkap dalam huruf besar. Setelah dua detik, kami akan mensimulasikan perubahan dan memperbarui tampilan.
// EXAMPLE USING EMBER App = Ember.Application.create(); App.Person = Ember.Object.extend({ firstName: null, lastName: null, fullName: function() { return this.get('firstName') + ' ' + this.get('lastName'); }.property('firstName', 'lastName') }); var person = App.Person.create({ firstName: "John", lastName: "Doe" }); Ember.Handlebars.helper('upcase', function(value) { return value.toUpperCase(); }); App.IndexRoute = Ember.Route.extend({ model: function () { return person; } }); setTimeout(function() { person.set('firstName', 'Harry'); }, 2000); // Templates: <script type="text/x-handlebars"> <h2>Welcome to Ember.js</h2> {{outlet}} </script> <script type="text/x-handlebars" data-template-name="index"> The current user is: {{upcase model.fullName}} </script>
Kami membuat objek dengan properti firstName
, lastName
, dan fullName
. Karena Ember mengamati perubahan properti, kami harus menentukan bahwa fullName
bergantung pada firstName
dan lastName
. Untuk melakukan ini, kami menambahkan .property('firstName', 'lastName')
ketika kami mendefinisikan fullName
.
Setelah dua detik, person.set('firstName', 'Harry');
dieksekusi. Ini memicu pembaruan tampilan dan pengikatannya.
Sekarang mari kita lakukan hal yang sama di React.
// EXAMPLE USING REACT var CurrentUser = React.createClass({ render: function() { return <div>The current user is: {this.props.user.fullName().toUpperCase()}</div>; } }); var person = { firstName: 'John', lastName: 'Doe', fullName: function() { return this.firstName + ' ' + this.lastName; } }; var currentUser = React.render(<CurrentUser user={person}/>, document.body); setTimeout(function() { person.firstName = 'Harry'; currentUser.setProps({user: person}); }, 2000);
Meskipun kode Ember sederhana dan mudah dibaca, jelas bahwa React menang dalam kesederhanaan. person
tersebut adalah objek JavaScript biasa, dengan nama fullName
hanya menjadi sebuah fungsi.
Tanpa Templat
Setiap kerangka alternatif memiliki cara penanganan template yang berbeda. Beberapa dari mereka menggunakan string yang dikompilasi ke dalam JavaScript, sementara yang lain menggunakan elemen DOM secara langsung. Kebanyakan dari mereka menggunakan atribut dan tag HTML khusus yang kemudian "dikompilasi" menjadi HTML.
Template bukan bagian dari kode JavaScript. Karena itu, setiap alternatif memerlukan cara khusus untuk mewakili operasi umum, kondisional, iterasi, fungsi pemanggilan, dll. Semuanya berakhir dengan menciptakan bahasa semu baru yang harus dipelajari oleh pengembang.
Tidak ada templating di React, semuanya hanyalah JavaScript lama.
Bereaksi menggunakan kekuatan penuh JavaScript untuk menghasilkan tampilan. Metode render komponen adalah fungsi JavaScript.
JSX tersedia sebagai praprosesor yang mengubah "sintaks seperti HTML" menjadi JavaScript normal, tetapi JSX adalah opsional dan Anda bebas menggunakan JavaScript standar tanpa praprosesor apa pun. Anda juga dapat memanfaatkan alat JavaScript yang ada. Linter, praprosesor, anotasi tipe, minifikasi, eliminasi kode mati, dll.
Mari kita kembali menggunakan contoh konkret untuk membandingkan React dengan salah satu kerangka kerja alternatif untuk manajemen status tampilan.
Tutorial berikut adalah contoh penggunaan AngularJS untuk membuat daftar tagar dan jumlah tweet untuk masing-masing tagar. Daftar diurutkan berdasarkan jumlah, dan pesan ditampilkan jika tidak ada tagar.
<!-- EXAMPLE USING ANGULAR --> <div ng-controller="MyCtrl"> <ul ng-show="hashTags.length > 0"> <li ng-repeat="hashTag in hashTags | orderBy:'tweetCount':true"> {{hashTag.name}} - {{hashTag.tweetCount}} tweets </li> </ul> <span ng-show="hashTags.length == 0">No hashtags found!</span> </div>
Untuk dapat membuat daftar ini, seorang developer harus mempelajari tentang AngularJS directives
, ng-show
dan ng-repeat
. Kemudian dia perlu belajar tentang AngularJS filters
untuk memahami orderBy
. Banyak pekerjaan untuk hal sederhana seperti membuat daftar!
Sekarang mari kita perhatikan contoh React yang melakukan hal yang sama:
// EXAMPLE USING REACT function byTweetCountDesc(h1, h2) { return h2.tweetCount - h1.tweetCount; } //... render: function() { if (this.state.hashTags.length > 0) { var comps = this.state.hashTags.sort(byTweetCountDesc).map(function(hashTag, index) { return <li key={index}> {hashTag.name} - {hashTag.tweetCount} tweets </li>; }); return <ul>{comps}</ul>; } else { return <span>No hashtags found!</span> } }
Meskipun kami menggunakan pendekatan “lebih maju” dan JSX, setiap pengembang web dengan pemahaman dasar tentang JavaScript dapat dengan mudah membaca kode di atas dan memahami fungsinya. Pemeriksaan bersyarat standar menggunakan if
, iterasi menggunakan map()
, dan standar 'sort()' datang secara alami ke pengembang mana pun, jadi tidak ada sintaks tambahan atau konsep lain untuk dipelajari.
Kesimpulan
Kesimpulan utama dari tutorial React.js ini adalah fakta bahwa React memungkinkan Anda untuk fokus pada manajemen status tampilan yang sebenarnya daripada transisi, sehingga menyederhanakan pekerjaan dan aplikasi Anda.
Kurva pembelajaran untuk mengadopsi React cukup sepele. Tidak ada bahasa templating khusus untuk dikuasai, tidak ada pengikatan data yang perlu dikhawatirkan, dan semuanya bermuara pada fungsi JavaScript yang menjelaskan elemen UI.
Untuk mempelajari lebih lanjut tentang menyederhanakan kode aplikasi Anda menggunakan React, lihat ceramah Steven Luscher, Decomplexifying Code with React.
Berikut adalah beberapa bacaan tambahan untuk siapa saja yang ingin mengambil langkah berikutnya dan mulai menggunakan React:
- http://jlongster.com/Removing-User-Interface-Complexity,-or-Why-React-is-Awesome