Gambaran Basis Kode
Bagian ini akan memberikan Anda gambaran mengenai penyusunan basis kode React, konvensi, serta implementasinya.
Jika Anda ingin berkontribusi pada React kami berharap panduan ini akan membantu Anda merasa lebih nyaman dalam membuat perubahan.
Kami tidak selalu merekomendasikan konvensi ini pada aplikasi React. Banyak di antaranya ada karena alasan historis dan mungkin berubah seiring berjalannya waktu.
Folder Level Atas
Setelah melakukan kloning pada repositori React, Anda akan melihat beberapa folder teratas di dalamnya:
packages
berisi metadata (sepertipackage.json
) dan kode sumber (src
subdirektori) untuk semua package pada repositori React. Jika perubahan Anda berkaitan dengan kode, subdirektorisrc
dari setiap package adalah dimana Anda akan menghabiskan sebagian besar waktu Anda.fixtures
berisi beberapa aplikasi uji coba React untuk para kontributor.build
adalah output build dari React. Ia tidak ada pada repositori tetapi akan muncul pada hasil klon React Anda setelah Anda melakukan build untuk pertama kali.
Dokumentasi berada pada repositori terpisah dari React.
Ada beberapa folder teratas lainnya tetapi mereka sebagian besar digunakan untuk peralatan dan kemungkinan besar Anda tidak akan pernah menghadapi mereka ketika berkontribusi.
Tes Kolokasi
Kami tidak memiliki direktori level atas untuk tes unit. Sebagai gantinya, kami meletakkannya pada direktori bernama __tests__
, relatif pada file yang ditesnya.
Misalnya, tes untuk setInnerHTML.js
terletak tepat di sampingnya pada __tests__/setInnerHTML-test.js
.
Peringatan dan Invariant
Basis kode React menggunakan modul warning
untuk menampilkan peringatan:
if (__DEV__) {
console.error('Something is wrong.');
}
Peringatan hanya diaktifkan pada mode pengembangan. Pada mode produksi, mereka dilepas seluruhnya. Jika Anda perlu melarang beberapa jalur kode untuk dijalankan, gunakan modul invariant
:
var invariant = require('invariant');
invariant(
2 + 2 === 4,
'Anda tidak boleh lewat!'
);
Invariant dilontarkan ketika kondisiinvariant
adalah false
.
”Invariant” hanya cara lain untuk mengatakan “kondisi ini selalu benar”. Anda dapat menganggapnya sebagai membuat assertion.
Merupakan hal yang penting untuk menjaga perilaku versi pengembangan dan produksi tetap serupa, sehingga invariant
dilontarkan baik di mode pengembangan dan produksi. Pesan eror secara otomatis diganti dengan kode eror pada mode produksi untuk menghindari mempengaruhi ukuran byte secara negatif.
Pengembangan dan Produksi
Anda dapat menggunakan variabel pseudo-global __DEV__
pada basis kode untuk menjaga blok kode yang ditujukan hanya pada mode pengembangan.
Variabel ini di-inline pada tahap kompilasi, dan berubah menjadi pengecekan process.env.NODE_ENV !== 'production'
pada build CommonJS.
Untuk build yang berdiri sendiri, ia menjadi true
pada build yang tidak di -minify, dan dilepas seluruhnya dengan menggunakan blok if
yang ia jaga pada build yang di-minify.
if (__DEV__) {
// Kode ini hanya akan berjalan di mode pengembangan.
}
Flow
Kami baru saja mulai memperkenalkan pengecekan Flow pada basis kode. File yang ditandai dengan anotasi @flow
pada komentar lisensi header mengalami pengecekan tipe.
Kami menerima pull request menambahkan anotasi Flow pada kode yang sudah ada. Anotasi Flow terlihat seperti ini:
ReactRef.detachRefs = function(
instance: ReactInstance,
element: ReactElement | string | number | null | false,
): void {
// ...
}
Bila mungkin, kode baru harus menggunakan anotasi Flow.
Anda dapat menjalankan yarn flow
secara lokal untuk mengecek kode Anda menggunakan Flow.
Multiple Package
React adalah sebuah monorepo. Repositorinya berisi banyak package terpisah sehingga perubahan mereka dapat dikoordinasikan bersama, dan isu-isu berada pada satu tempat.
Inti React
Inti dari React berisi semua API level atas React
, misalnya:
React.createElement()
React.Component
React.Children
Inti React hanya berisi API yang dibutuhkan untuk mendefinisikan komponen. Ia tidak termasuk algoritma reconciliation atau kode spesifik platform lainnya. Ia digunakan oleh React DOM dan komponen React Native.
Kode untuk inti React terletak di packages/react
pada diagram sumber. Ia tersedia pada npm sebagai package react
. Build browser yang berdiri sendiri disebut react.js
, dan ia mengekspor sebuah global yang disebut React
.
Renderer
React mulanya dibuat demi DOM tetapi kemudian diadaptasi untuk mendukung platform native dengan React Native. Hal ini memperkenalkan konsep renderer pada tim internal React.
Renderer mengatur bagaimana sebuah diagram React berubah menjadi panggilan platform yang mendasarinya
Renderer juga terletak pada packages/
:
- Renderer React DOM merender komponen React menuju DOM. Ia mengimplementasi API
ReactDOM
level atas dan tersedia sebagai package npmreact-dom
. Ia juga bisa digunakan sebagai bundel browser yang berdiri sendiri yang dikenalreact-dom.js
yang mengekspor sebuah globalReactDOM
. - Renderer React Native merender komponen React menuju tampilan native. Ia digunakan secara internal oleh React Native.
- Renderer React Test merender komponen React menuju diagram JSON. Ia digunakan oleh fitur Snapshot Testing dari Jest dan tersedia sebagai package npm react-test-renderer.
Satu-satunya Renderer lain yang didukung secara resmi adalah react-art
. Ia dulu terletak pada repositori GitHub terpisah tetapi kami memindahkannya pada diagram sumber main sekarang.
Catatan:
Secara teknis
react-native-renderer
adalah sebuah lapisan yang sangat tipis yang mengajarkan React untuk berinteraksi dengan implementasi React Native. Kode spesifik platform yang sesungguhnya mengatur tampilan native yang hidup di dalam repositori React Native bersama dengan komponennya.
Reconciler
Bahkan renderer yang sangat berbeda seperti React DOM dan React Native perlu berbagi banyak logika. Khususnya, algoritma reconciliation harus semirip mungkin agar proses render deklaratif, komponen kustom, state, metode lifecycle, dan refs bekerja secara konsisten antar platform.
Untuk menyelesaikan hal ini, renderer berbeda berbagi beberapa kode di antara mereka. Kami menyebut bagian React ini sebuah ”reconciler”. Ketika sebuah pembaruan seperti setState()
dijadwalkan, reconciler memanggil render()
pada komponen di diagram, dan memasang, membarui, atau melepas mereka.
Reconciler tidak dipaketkan terpisah karena saat ini mereka tidak memiliki API publik. Sebagai gantinya, mereka digunakan secara eksklusif oleh renderer seperti React DOM dan React Native.
Reconciler Stack
Reconciler “stack” adalah implementasi yang menggerakan React 15 dan versi sebelumnya. Kami telah berhenti menggunakannya, tapi ia didokumentasikan dengan detil di bagian berikutnya
Reconciler Fiber
Reconciler “fiber” adalah usaha baru untuk menyelesaikan masalah yang melekat pada reconciler stack dan memperbaiki beberapa isu yang telah lama ada. Ia telah menjadi reconciler default sejak React 16.
Tujuan utamanya adalah:
- Kemampuan untuk membagi tugas yang dapat diinterupsi menjadi potongan kecil.
- Kemampuan untuk memprioritaskan, rebase dan menggunakan kembali tugas yang sedang berjalan.
- Kemampuan untuk bolak-balik antara parent dan children untuk mendukung layout pada React.
- Kemampuan untuk mengembalikan beberapa elemen dari
render()
. - Dukungan yang lebih baik untuk batasan eror.
Anda dapat membaca lebih banyak mengenai Arsitektur React Fiber di sini dan di sini. Walaupun ia telah dikirimkan bersama dengan React 16, fitur-fitur async belum diaktifkan secara default.
Kode sumbernya terletak di packages/react-reconciler
.
Sistem Event
<<<<<<< HEAD
React menerapkan sebuah sistem event sintetis yang agnostik terhadap renderer-nya dan bekerja dengan React DOM dan React Native. Kode sumbernya terletak di packages/react-events
.
Terdapat sebuah video dengan pembahasan mendalam mengenai kodenya (66 menit).
React implements a layer over native events to smooth out cross-browser differences. Its source code is located in packages/react-dom/src/events
.
25cc703d1f23f1782ff96c5c7882a806f8741ec4
Selanjutnya Apa?
Bacalah bagian berikutnya untuk mempelajari mengenai implementasi reconciler sebelum React 16 secara lebih detil. Kami belum mendokumentasikan bagian internal dari reconciler yang baru.