Berkenalan Dengan React Framework



Dalam dunia Javascript Application frameworks saat ini, filosofi desain adalah faktor pembeda utama. Jika Anda membandingkan kerangka JS populer, seperti EmberJS, AngularJS, Backbone, Knockout, dll. Anda pasti akan menemukan perbedaan dalam abstraksi, model pemikiran, dan tentu saja terminologinya. Ini adalah konsekuensi langsung dari filosofi desain yang mendasarinya. Tapi, pada prinsipnya, mereka semua melakukan satu hal, yaitu untuk mengabstraksi DOM sedemikian rupa sehingga Anda tidak berhubungan langsung dengan Elemen HTML.

Saya pribadi berpikir bahwa framework menjadi menarik ketika itu menyediakan seperangkat abstraksi yang memberikan cara berpikir yang berbeda. Dalam aspek ini, React, framework JS baru dari orang-orang di Facebook, akan memaksa Anda untuk memikirkan kembali (sampai batas tertentu) bagaimana Anda menguraikan UI dan interaksi aplikasi Anda. Setelah mencapai versi 16.9.0 (pada tulisan ini), React menyediakan model yang sangat sederhana namun efektif untuk membuat aplikasi JS yang mencampurkan koktail menyenangkan dari jenis yang berbeda.

Dalam artikel kali ini, kita akan menjelajahi building blocks React dan merangkul style of thinking yang mungkin tampak berlawanan dengan intuisi pada langkah pertama. Tapi, seperti yang dikatakan oleh React docs: "Beri Lima Menit" dan kemudian Anda akan melihat bagaimana pendekatan ini akan menjadi lebih alami.


Kisah React dimulai dalam batasan Facebook, di mana ia dibuat untuk sementara waktu. Setelah mencapai keadaan yang cukup stabil, developer memutuskan untuk open source itu beberapa tahun yang lalu. Menariknya situs web Instagram juga didukung oleh React Framework.

React mendekati masalah abstraksi DOM dengan pengambilan yang sedikit berbeda. Untuk memahami bagaimana hal ini berbeda, mari kita cepat menghapus teknik yang diadopsi oleh framework yang saya sebutkan sebelumnya.


Pola desain MVC (Model-View-Controller) sangat penting untuk pengembangan UI, tidak hanya di aplikasi web, tetapi di aplikasi front-end pada platform apa pun. Dalam hal aplikasi web, DOM adalah representasi fisik dari suatu View. DOM itu sendiri dihasilkan dari html-template tekstual yang ditarik dari file yang berbeda, skrip-blok atau fungsi template dikompilasi. The View adalah entitas yang membawa template tekstual untuk hidup sebagai fragmen DOM. Ini juga mengatur penanganan-event dan menangani manipulasi pohon DOM sebagai bagian dari siklus hidupnya.

Agar View bermanfaat, perlu menunjukkan beberapa data, dan mungkin memungkinkan interaksi pengguna. Data adalah Model, yang berasal dari beberapa resource (database, layanan web, penyimpanan lokal, dll.). Framework menyediakan cara "binding" data ke interface, sehingga perubahan data secara otomatis tercermin dengan perubahan pada interface. Proses otomatis ini disebut pengikatan data dan ada API / teknik untuk menjadikan ini semulus mungkin.

Triad MVC dilengkapi oleh Controller, yang melibatkan View dan Model> dan mengatur aliran data (Model) ke dalam View dan peristiwa pengguna keluar dari View, kemungkinan mengarah pada perubahan dalam Model.



Framework yang secara otomatis menangani aliran data bolak-balik antara View dan Model mempertahankan loop event internal. Event-loop ini diperlukan untuk mendengarkan event pengguna tertentu, event perubahan data, pemicu eksternal, dll dan kemudian menentukan apakah ada perubahan dari sebelumnya menjalankan loop. Jika ada perubahan, pada salah satu ujung (Lihat atau Model), framework memastikan bahwa keduanya dibawa kembali dalam sinkronisasi.


Dengan React, View-bagian dari MVC triad menjadi prominence dan rolled ke dalam entitas yang disebut Komponen. Komponen mempertahankan tas properti yang tidak berubah yang disebut props, dan keadaan yang mewakili keadaan pengguna yang digerakkan oleh pengguna. Bagian view-generation dari Komponen agak menarik dan mungkin alasan yang membuat React menonjol dibandingkan dengan framework lain. Alih-alih membangun DOM fisik langsung dari file template / skrip/fungsi, Komponen menghasilkan DOM perantara yang merupakan stand-in untuk DOM HTML yang sebenarnya. Langkah tambahan selanjutnya diambil untuk menerjemahkan DOM perantara ini ke dalam DOM HTML yang sebenarnya.

Sebagai bagian dari generasi DOM perantara, Komponen juga melampirkan penangan kejadian dan binding data yang terdapat dalam alat peraga dan status.

Jika ide dari DOM menengah terdengar sedikit asing, jangan terlalu khawatir. Anda telah melihat strategi ini diadopsi oleh runtimes bahasa (alias Mesin Virtual) untuk bahasa yang ditafsirkan. Runtime JavaScript kaita sendiri, yang pertama menghasilkan representasi antara sebelum spitting native kode. Ini juga berlaku untuk bahasa berbasis VM lainnya seperti Java, C #, Ruby, Python, dll.

React dengan cerdik mengadopsi strategi ini untuk membuat DOM perantara sebelum menghasilkan DOM HTML final. DOM menengah hanya berupa grafik objek JavaScript dan tidak dirender secara langsung. Ada langkah terjemahan yang menciptakan DOM asli. Ini adalah teknik dasar yang membuat React melakukan manipulasi DOM dengan cepat.


Untuk mendapatkan gambaran yang lebih baik tentang cara React membuat semuanya berfungsi, mari selami sedikit lebih dalam; dimulai dengan Komponen. Komponen adalah blok bangunan utama dalam React. Anda dapat menyusun UI aplikasi Anda dengan mengumpulkan Component-tree. Setiap Komponen menyediakan implementasi untuk metode render(), di mana ia menciptakan DOM menengah. Memanggil React.renderComponent() pada root Komponen menghasilkan secara berurutan menurunkan Component-tree dan membangun intermediate-DOM. DOM menengah kemudian diubah menjadi DOM HTML asli.



Karena pembuatan DOM menengah merupakan bagian integral dari Komponen, React menyediakan ekstensi berbasis XML yang mudah digunakan untuk JavaScript, yang disebut JSX, untuk membangun Component-tree sebagai sekumpulan node XML. Ini membuatnya lebih mudah untuk memvisualisasikan dan bernalar tentang DOM. JSX juga menyederhanakan asosiasi event-handler dan properti sebagai atribut xml. Karena JSX adalah bahasa ekstensi, ada alat (baris perintah dan di-browser) untuk menghasilkan JavaScript akhir. Sebuah node XML JSX memetakan langsung ke Komponen. Perlu diketahui bahwa React bekerja independen dari JSX dan bahasa JSX hanya mempermudah pembuatan DOM perantara.


Framework inti React dapat diunduh dari situs web mereka. Selain itu, untuk transformasi JSX → JS, Anda dapat menggunakan JSXTransformer di-browser atau menggunakan alat baris perintah, yang disebut react-tools (diinstal melalui NPM). Anda perlu menginstal Node.js untuk mengunduhnya. Alat baris perintah memungkinkan Anda mengkompilasi file JSX dan menghindari terjemahan dalam browser. Ini pasti direkomendasikan jika file JSX Anda besar atau banyak jumlahnya.


Baiklah, kita telah melihat banyak teori sejauh ini, dan saya yakin Anda gatal untuk melihat beberapa kode nyata. Mari selami contoh pertama kita:

1:  /** @jsx React.DOM */  
2:  var Simple = React.createClass({  
3:   getInitialState: function(){  
4:    return { count: 0 };  
5:   },  
6:   handleMouseDown: function(){  
7:    alert('I was told: ' + this.props.message);  
8:    this.setState({ count: this.state.count + 1});  
9:   },  
10:   render: function(){  
11:    return <div>  
12:     <div class="clicker" onMouseDown={this.handleMouseDown}>  
13:      Give me the message!  
14:     </div>  
15:     <div class="message">Message conveyed  
16:      <span class="count">{this.state.count}</span> time(s)</div>  
17:    </div>  
18:    ;  
19:   }  
20:  });  
21:  React.renderComponent(<Simple message="Keep it Simple"/>,  
22:           document.body);  


Meskipun sederhana, kode di atas tidak mencakup jumlah luas permukaan React yang baik:

  • Kita membuat komponen sederhana dengan menggunakan React.createClass dan meneruskan objek yang mengimplementasikan beberapa fungsi inti. Yang paling penting adalah render(), yang menghasilkan intermediate-DOM.
  • Di sini kita menggunakan JSX untuk menentukan DOM dan juga melampirkan mousedown event-handler. Sintaks {} berguna untuk menggabungkan ekspresi JavaScript untuk atribut (onMouseDown={this.handleClick}) dan child-nodes (<span class="count'> {this.state.count}</span>). Event handlers yang terkait menggunakan {} sintaks secara otomatis terikat ke instance komponen. Jadi this di dalam fungsi event-handler mengacu pada contoh komponen. Komentar di baris pertama /** @jsx React.DOM */ adalah isyarat untuk transformator BEJ untuk melakukan penerjemahan ke JS. Tanpa baris komentar ini, tidak ada terjemahan yang akan terjadi.
 
    Kita dapat menjalankan line tool perintah (jsx) dalam watch mode dan perubahan auto-compile dari JSX → JS. source files berada di folder / src dan output dihasilkan di / build.


    1:  jsx --watch src/ build/  
    

    Berikut file JS yang dihasilkan:


    1:  /** @jsx React.DOM */  
    2:  var Simple = React.createClass({displayName: 'Simple',  
    3:   getInitialState: function(){  
    4:    return { count: 0 };  
    5:   },  
    6:   handleMouseDown: function(){  
    7:    alert('I was told: ' + this.props.message);  
    8:    this.setState({ count: this.state.count + 1});  
    9:   },  
    10:   render: function(){  
    11:    return React.DOM.div(null,   
    12:     React.DOM.div( {className:"clicker", onMouseDown:this.handleMouseDown},   
    13:  " Give me the message! "   ),  
    14:     React.DOM.div( {className:"message"}, "Message conveyed ",    React.DOM.span( {className:"count"}, this.state.count), " time(s)")  
    15:    )  
    16:    ;  
    17:   }  
    18:  });  
    19:  React.renderComponent(Simple( {message:"Keep it Simple"}),  
    20:           document.body);  
    


    Perhatikan bagaimana tag <div/> dan <span/> memetakan ke intance React.DOM.div dan React.DOM.span.

    • Sekarang mari kita kembali ke contoh kode kita. Di dalam handleMouseDown, kita menggunakan this.props untuk membaca message property yang diteruskan. Kita mengatur message pada baris terakhir dari snippet, dalam panggilan ke React.renderComponent() dimana kita membuat <Simple/> komponen. Tujuan this.props adalah untuk menyimpan data yang diteruskan ke komponen. Hal ini dianggap tidak dapat diubah dan hanya komponen tingkat yang lebih tinggi yang diperbolehkan untuk melakukan perubahan dan meneruskannya ke component tree.
    • Di dalam handleMouseDown kita juga mengatur beberapa user state dengan this.setState() untuk melacak berapa kali pesan ditampilkan. Anda akan melihat bahwa kita menggunakan this.state dalam metode render(). Setiap kali Anda memanggil setState(), React juga memicu metode render() untuk menjaga DOM tetap sinkron. Selain React.renderComponent(), setState() adalah cara lain untuk memaksa visual refresh.


    Peristiwa yang terekspos pada intermediate-DOM, seperti onMouseDown, juga bertindak sebagai layer of indirection sebelum mereka ditetapkan pada DOM asli. Kejadian-kejadian ini dengan demikian disebut sebagai Peristiwa Sintetis (Synthetic Events). React mengadopsi event-delegation, yang merupakan teknik yang terkenal, dan hanya melampirkan peristiwa di root-level DOM asli. Dengan demikian hanya ada satu event-handler sejati di DOM asli. Selain itu, peristiwa sintetis ini juga memberikan tingkat konsistensi dengan menyembunyikan browser dan perbedaan elemen.

    Kombinasi event antara-DOM dan sintetis memberi Anda cara standar dan konsisten mendefinisikan UI di berbagai browser dan bahkan perangkat.


    Komponen dalam Framework React memiliki siklus hidup spesifik ( specific lifecycle ) dan mewujudkan state-machine yang memiliki tiga kondisi berbeda.

    Komponen menjadi hidup setelah Dipasang. Memasang hasil dalam melewati render-pass yang menghasilkan component-tree (intermediate-DOM). Tree ini diubah dan ditempatkan ke dalam wadah-node dari DOM asli. Ini adalah hasil yang langsung panggilan untuk React.renderComponent().

    Setelah dipasang, komponen tetap dalam Update state. Komponen akan diperbarui ketika Anda mengubah status menggunakan setState() atau mengubah properti menggunakan setProps(). Ini pada gilirannya menghasilkan panggilan render(), yang membawa DOM dalam sinkron dengan data (properti + state). Di antara pembaruan berikutnya, React akan menghitung delta antara component-tree sebelumnya dan pohon yang baru dibuat. Ini adalah langkah yang sangat dioptimalkan (dan fitur unggulan) yang meminimalkan manipulasi pada DOM asli.

    final state adalah Unmounted. Ini terjadi ketika Anda secara eksplisit memanggil React.unmountAndReleaseReactRootNode() atau secara otomatis jika komponen adalah anak yang tidak lagi dihasilkan dalam render() panggilan. Paling sering Anda tidak perlu berurusan dengan ini dan biarkan saja React melakukan hal yang tepat.

    Sekarang itu akan menjadi remiss yang besar, jika React tidak memberi tahu Anda ketika itu bergerak di antara bagian Mounted-Update-Unmounted. Untungnya itu tidak terjadi dan ada hooks yang bisa Anda ganti untuk mendapatkan pemberitahuan perubahan lifecycle. Nama-nama berbicara sendiri:

    • getInitialState(): siapkan keadaan awal Komponen
    • componentWillMount()
    • componentDidMount()
    • componentWillReceiveProps()
    • shouldComponentUpdate(): berguna jika Anda ingin mengontrol kapan render harus dilewati.
    • componentWillUpdate()
    • render()
    • componentDidUpdate()
    • componentWillUnmount()

    Metode componentWill* dipanggil sebelum perubahan status dan metode componentDid* dipanggil sesudahnya.

    Beberapa nama metode tampaknya telah mengambil isyarat dari Cocoa frameworks di Mac dan iOS 

    Di dalam bagan komponen, data harus selalu mengalir ke bawah. Komponen induk harus mengatur props komponen anak untuk meneruskan data apa pun dari induk ke anak. Ini disebut sebagai pasangan Owner-Owned. Di sisi lain, peristiwa pengguna (mouse, keyboard, touch) akan selalu meluap dari anak sampai ke komponen root, kecuali ditangani di antara keduanya.



    Saat Anda membuat intermediate-DOM di render(), Anda juga dapat menetapkan properti ref ke komponen anak (child). Anda kemudian dapat merujuknya dari induk (parent) menggunakan properti refs. Ini digambarkan dalam potongan di bawah ini.

    1:  render: function(){  
    2:    // Set a ref   
    3:    return <div>  
    4:      <span ref="counter" class="count">{this.state.count}</span>  
    5:      </div>;  
    6:   }  
    7:   handleMouseDown: function(){  
    8:    // Use the ref  
    9:    console.log(this.refs.counter.innerHTML);  
    10:   },  
    


    Sebagai bagian dari component metadata, Anda dapat mengatur initial-state (getInitialState ()), yang kita lihat sebelumnya dalam metode siklus hidup (lifecycle methods). Anda juga dapat mengatur nilai default dari props dengan getDefaultProps() dan juga menetapkan beberapa validation rules pada props ini menggunakan propTypes. Dokumentasi memberikan gambaran bagus tentang berbagai jenis validasi (jenis checks, required, etc.) Yang dapat Anda lakukan.

    React juga mendukung konsep Mixin untuk mengekstrak reusable pieces yang dapat digunakan kembali yang dapat disuntikkan ke dalam Komponen yang berbeda. Anda dapat melewatkan mix-mix menggunakan properti mixins dari Component.

    Sekarang, mari kita membuatnya dan membangun Komponen yang lebih komprehensif yang menggunakan fitur ini.


    Dalam contoh ini, kita akan membangun editor yang menerima DSL sederhana (Bahasa Khusus Domain) untuk membuat bentuk (Shape). Saat Anda mengetik, Anda akan melihat output yang sesuai di samping, memberi Anda umpan balik langsung.

    DSL memungkinkan Anda untuk membuat tiga jenis bentuk: Ellipse, Rectangle, dan Text. Setiap bentuk ditentukan pada garis terpisah bersama dengan sekelompok properti styling. Sintaksnya mudah dan meminjam sedikit dari CSS. Untuk menguraikan baris, kita menggunakan Regex yang terlihat seperti:

    1:  var shapeRegex = /(rect|ellipse|text)(\s[a-z]+:\s[a-z0-9  
    


    Sebagai contoh, rangkaian garis berikut menggambarkan dua persegi panjang dan label teks ...

    1:  // React label  
    2:  text value:React; color: #00D8FF; font-size: 48px; text-shadow: 1px 1px 3px #555; padding: 10px; left: 100px; top: 100px;  
    3:  // left logo  
    4:  rect background:url(react.png) no-repeat; border: none; width: 38; height: 38; left: 60px; top: 120px;  
    5:  // right logo  
    6:  rect background:url(react.png) no-repeat; border: none; width: 38; height: 38; left: 250px; top: 120px;  
    




    Baiklah, ayo lanjutkan dan buat editor ini. Kita akan memulai dengan file HTML (index.html), tempat kita menempatkan top-level markup dan menyertakan libraries dan skrip aplikasi. Saya hanya menunjukkan bagian yang relevan di sini:

    1:  <body>  
    2:  <select class="shapes-picker">  
    3:   <option value="--">-- Select a sample --</option>  
    4:   <option value="react">React</option>  
    5:   <option value="robot">Robot</option>  
    6:  </select>  
    7:  <div class="container"></div>  
    8:  <!-- Libraries -->  
    9:  <script src="../../lib/jquery-2.0.3.min.js"></script>  
    10:  <script src="../../lib/react.js"></script>  
    11:  <!-- Application Scripts -->  
    12:  <script src="../../build/shape-editor/ShapePropertyMixin.js"></script>  
    13:  <script src="../../build/shape-editor/shapes/Ellipse.js"></script>  
    14:  <script src="../../build/shape-editor/shapes/Rectangle.js"></script>  
    15:  <script src="../../build/shape-editor/shapes/Text.js"></script>  
    16:  <script src="../../build/shape-editor/ShapeParser.js"></script>  
    17:  <script src="../../build/shape-editor/ShapeCanvas.js"></script>  
    18:  <script src="../../build/shape-editor/ShapeEditor.js"></script>  
    19:  <script src="../../build/shape-editor/shapes.js"></script>  
    20:  <script src="../../build/shape-editor/app.js"></script>  
    21:  </body>  
    


    Dalam snippet di atas, div kontainer menyimpan DOM hasil react kita. application scripts kita termasuk dari direktori /build. Kita menggunakan JSX dalam komponen kita dan command line watcher (jsx), menempatkan file JS yang telah dikonversi ke dalam /build. Perhatikan bahwa watcher command ini adalah bagian dari modul NPM react-tools.

    1:  jsx --watch src/ build/  
    


    Editor dibagi menjadi beberapa komponen, yang tercantum di bawah ini:

    • ShapeEditor: Komponen root di component tree
    • ShapeCanvas: bertanggung jawab untuk menghasilkan bentuk-Komponen (Ellipse, Rectangle, Text). Ini terkandung dalam ShapeEditor.
    • ShapeParser: bertanggung jawab untuk mengurai teks dan mengekstraksi daftar definisi bentuk. Ini mem-parsing baris demi baris dengan Regex yang kita lihat sebelumnya. Baris tidak valid diabaikan. Ini bukan benar-benar sebuah komponen, tetapi objek JS pembantu, yang digunakan oleh ShapeEditor.
    • Ellipse, Rectangle, Teks: Komponen bentuk. Ini menjadi anakan dari ShapeCanvas.
    • ShapePropertyMixin: menyediakan fungsi pembantu untuk mengekstraksi gaya yang ditemukan dalam definisi bentuk. Ini dicampur ke dalam tiga bentuk-Komponen menggunakan properti mixins.
    • app: entry-point untuk editor. Ini menghasilkan komponen root (ShapeEditor) dan memungkinkan Anda untuk mengambil sampel bentuk dari drop-down.
    Hubungan entitas ini ditampilkan dalam annotated component-tree:



    Mari kita lihat penerapan beberapa komponen ini, dimulai dengan ShapeEditor.

    1:  /** @jsx React.DOM */  
    2:  var ShapeEditor = React.createClass({  
    3:   componentWillMount: function () {  
    4:    this._parser = new ShapeParser();  
    5:   },  
    6:   getInitialState: function () {  
    7:    return { text: '' };  
    8:   },  
    9:   render: function () {  
    10:    var shapes = this._parser.parse(this.state.text);  
    11:    var tree = (  
    12:     <div>  
    13:      <textarea class="editor" onChange={this.handleTextChange} />  
    14:      <ShapeCanvas shapes={shapes} />  
    15:     </div>);  
    16:    return tree;  
    17:   },  
    18:   handleTextChange: function (event) {  
    19:    this.setState({ text: event.target.value })  
    20:   }  
    21:  });  
    


    Seperti namanya, ShapeEditor menyediakan pengalaman pengeditan dengan menghasilkan <textarea/> dan live feedback <ShapeCanvas/<. Ini mendengarkan event onChange (event di React selalu dinamai dengan camel case) pada <textarea /> dan pada setiap perubahan mengatur properti teks dari state komponen. Seperti disebutkan sebelumnya, setiap kali Anda mengatur state menggunakan setState(), render dipanggil secara otomatis. Dalam hal ini, render() dari ShapeEditor dipanggil di mana kita mengurai teks dari bagian dan membangun kembali bentuk. Perhatikan bahwa kita memulai dengan keadaan awal teks kosong, yang diatur dalam hook getInitialState().
     
    Untuk mengurai teks menjadi satu set bentuk, Kita menggunakan turunan dari ShapeParser. Saya telah meninggalkan rincian parser untuk menjaga diskusi tetap fokus pada React. Instance parser dibuat di hook componentWillMount(). Ini disebut tepat sebelum mount komponen dan merupakan tempat yang baik untuk melakukan inisialisasi sebelum render pertama terjadi.
     
    Umumnya disarankan agar Anda menyalurkan semua pemrosesan kompleks Anda melalui metode render(). Event handlers hanya mengatur state saat render() adalah pusat untuk semua core logic Anda.

    ShapeEditor menggunakan ide ini untuk melakukan parsing di dalam render() dan meneruskan bentuk yang terdeteksi dengan mengatur properti shape ShapeCanvas. Ini adalah bagaimana data mengalir turun ke dalam component tree, dari pemilik (ShapeEditor) ke yang dimiliki (ShapeCanvas).

    Satu hal terakhir yang perlu diperhatikan di sini adalah kita memiliki komentar baris pertama untuk menunjukkan terjemahan JSX → JS.


    Selanjutnya, kita akan beralih ke komponen ShapeCanvas dan Ellipse, Rectangle and Text.
    p> ShapeCanvas lebih sederhana dengan tanggung jawab utamanya menghasilkan masing-masing <Ellipse/&gt; , <Rectangle/> dan <Text/> komponen dari definisi yang dilewati dalam bentuk (this.props.shapes). Untuk setiap bentuk, kita meneruskan properti parsing dengan ekspresi atribut: properties={shape.properties}.

    1:  /** @jsx React.DOM */  
    2:  var ShapeCanvas = React.createClass({  
    3:   getDefaultProps: function(){  
    4:    return {  
    5:     shapes: []  
    6:    };  
    7:   },  
    8:   render: function () {  
    9:    var self = this;  
    10:    var shapeTree = <div class="shape-canvas">  
    11:    {  
    12:     this.props.shapes.map(function(s) {  
    13:      return self._createShape(s);  
    14:     })  
    15:    }  
    16:     </div>;  
    17:    var noTree = <div class="shape-canvas no-shapes">No Shapes Found</div>;  
    18:    return this.props.shapes.length > 0 ? shapeTree : noTree;  
    19:   },  
    20:   _createShape: function(shape) {  
    21:    return this._shapeMap[shape.type](shape);  
    22:   },  
    23:   _shapeMap: {  
    24:    ellipse: function (shape) {  
    25:     return <Ellipse properties={shape.properties} />;  
    26:    },  
    27:    rect: function (shape) {  
    28:     return <Rectangle properties={shape.properties} />;  
    29:    },  
    30:    text: function (shape) {  
    31:     return <Text properties={shape.properties} />;  
    32:    }  
    33:   }  
    34:  });  
    


    Satu hal yang berbeda di sini adalah bahwa component tree kita tidak statis, seperti yang kita miliki di ShapeEditor. Sebaliknya itu secara dinamis dihasilkan oleh perulangan atas yang dilewati dalam bentuk. Kita juga menunjukkan pesan "No Shapes Found" jika tidak ada yang ditampilkan.


    Semua bentuk memiliki struktur yang serupa dan hanya berbeda dalam style. Mereka juga menggunakan ShapePropertyMixin untuk menangani style generation.

    Berikut adalah Ellipse:

    1:  /** @jsx React.DOM */  
    2:  var Ellipse = React.createClass({  
    3:   mixins: [ShapePropertyMixin],  
    4:   render:function(){  
    5:    var style = this.extractStyle(true);  
    6:    style['border-radius'] = '50% 50%';  
    7:    return <div style={style} class="shape" />;  
    8:   }  
    9:  });  
    


    Implementasi untuk extractStyle() disediakan oleh ShapePropertyMixin.

    Komponen Rectangle berikut sesuai, tentu saja tanpa gaya border-radius. Komponen Text memiliki value properti tambahan yang disebut yang menetapkan teks bagian dalam untuk <div/>.

    Ini Teks, untuk memperjelas ini:

    1:  /** @jsx React.DOM */  
    2:  var Text = React.createClass({  
    3:   mixins: [ShapePropertyMixin],  
    4:   render:function(){  
    5:    var style = this.extractStyle(false);  
    6:    return <div style={style} class="shape">{this.props.properties.value}</div>;  
    7:   }  
    8:  });  
    


    app.js adalah tempat kita menyatukan semuanya. Di sini kita membuat komponen root, ShapeEditor dan juga menyediakan dukungan untuk beralih di antara beberapa bentuk sampel.

    Ketika Anda memilih sampel yang berbeda dari drop down, kita memuat beberapa teks yang telah ditentukan ke ShapeEditor dan menyebabkan ShapeCanvas untuk memperbarui. Ini terjadi dalam metode readShapes().

    1:  /** @jsx React.DOM */  
    2:  var shapeEditor = <ShapeEditor />;  
    3:  React.renderComponent(  
    4:   shapeEditor,  
    5:   document.getElementsByClassName('container')[0]  
    6:  );  
    7:  function readShapes() {  
    8:   var file = $('.shapes-picker').val(),  
    9:    text = SHAPES[file] || '';  
    10:   $('.editor').val(text);  
    11:   shapeEditor.setState({ text: text }); // force a render  
    12:  }  
    13:  $('.shapes-picker').change(readShapes);  
    14:  readShapes(); // load time  
    


    Untuk melatih sisi kreatif, di sini adalah robot yang dibangun menggunakan Editor Bentuk:


    Fuih! Ini adalah artikel yang agak panjang dan setelah mencapai titik ini, Anda harus memiliki rasa pencapaian!

    Kita telah menjelajahi banyak konsep di sini: peran integral dari Komponen dalam kerangka kerja (framework), penggunaan JSX untuk dengan mudah menggambarkan component tree (aka intermediate-DOM), berbagai hooks untuk dicolokkan (plug) ke dalam lifecyle komponen, penggunaan status dan tools untuk drive the render process, penggunaan Mixins untuk factor out reusable behavior yang dapat digunakan kembali dan akhirnya menarik kesimpulan dari semua ini bersama dengan contoh Shape Editor.

    Saya harap artikel ini memberi Anda cukup dorongan untuk membuat beberapa aplikasi React untuk diri Anda sendiri. Untuk melanjutkan eksplorasi Anda, berikut beberapa tautan praktis: