5 praktik terbaik untuk menggunakan kait Bereaksi dalam produksi

Penulis artikel, terjemahan yang kami terbitkan hari ini, mengatakan bahwa commercetools mengadopsi kait React pada awal 2019 - pada saat mereka muncul di React 16.8.0. Sejak itu, pemrogram perusahaan terus memproses kode mereka, menerjemahkannya ke dalam kaitan. Bereaksi kait memungkinkan Anda untuk menggunakan status komponen dan menggunakan fitur Bereaksi lainnya tanpa menggunakan kelas. Menggunakan kait, Anda dapat, saat bekerja dengan komponen fungsional, "menyambungkan" ke peristiwa siklus hidup komponen dan menanggapi perubahan dalam statusnya.



Secara singkat tentang hasil penerapan kait


Jika singkatnya kita berbicara tentang apa yang diberikan oleh kait, ternyata mereka membantu menyederhanakan basis kode dengan mengekstraksi logika dari komponen dan memfasilitasi komposisi kemampuan yang berbeda. Selain itu, penggunaan kait telah menyebabkan fakta bahwa kami telah belajar banyak. Misalnya, cara menyusun struktur kode Anda dengan lebih baik melalui peningkatan berkesinambungan fungsi yang ada. Kami yakin bahwa kami akan mempelajari banyak hal menarik lainnya sambil terus bekerja dengan React hooks.

Kekuatan implementasi pengait


Inilah yang diberikan pengantar pada kami:

  • Meningkatkan keterbacaan kode. Ini dimungkinkan berkat penggunaan pohon komponen yang lebih kecil dari sebelumnya. Pembuatan komponen pohon tersebut difasilitasi oleh keinginan kami untuk meninggalkan properti rendering dan komponen tingkat tinggi.
  • Meningkatkan kemampuan debugging kode. Kami sudah memiliki perwakilan visual yang ditingkatkan dari kode dan informasi debug tambahan yang disediakan oleh alat pengembang Bereaksi.
  • Meningkatkan modularitas proyek. Karena sifat fungsional kait, proses membuat dan menerapkan logika yang cocok untuk penggunaan berulang telah disederhanakan.
  • Pemisahan tanggung jawab. Komponen Bereaksi bertanggung jawab atas penampilan elemen antarmuka, dan kait menyediakan akses ke logika program yang dienkapsulasi.

Sekarang kami ingin membagikan rekomendasi kami tentang penggunaan kait dalam produksi.

1. Ambil kait tepat waktu dari komponen dan buat kait kustom


Mulai menggunakan kait dalam komponen fungsional cukup mudah. Misalnya, kami dengan cepat melamar di suatu tempat React.useState, di suatu tempat - React.useEffectdan terus melakukan pekerjaan kami. Namun, pendekatan ini tidak memungkinkan untuk mengambil keuntungan penuh dari semua peluang yang mampu diberikan oleh kait. Mempresentasikan React.useStatedalam bentuk yang kecil use<StateName>State, dan React.useEffect- dalam bentuk use<EffectName>Effect, kami dapat mencapai yang berikut:

  1. Komponen lebih kecil daripada dengan kait biasa.
  2. Kait dapat digunakan kembali di berbagai komponen.
  3. , React, , . , State<StateName> State. React.useState, .

Mengambil kait juga berkontribusi pada fakta bahwa logika yang dapat digunakan kembali dan dibagikan lebih terlihat di berbagai bagian aplikasi. Logika yang serupa atau duplikat lebih sulit untuk diketahui jika Anda hanya menggunakan pengait yang dibangun ke dalam kode komponen. Kait yang dihasilkan bisa berukuran kecil dan mengandung sangat sedikit kode useToggleState. Di sisi lain, kait yang lebih besar, seperti useProductFetcher, sekarang dapat mencakup lebih banyak fungsi. Kedua hal ini membantu kami menyederhanakan basis kode dengan mengurangi ukuran komponen Bereaksi.

Contoh berikut membuat kait Bereaksi kecil yang dirancang untuk mengontrol pemilihan elemen. Manfaat enkapsulasi fungsi ini menjadi jelas segera setelah Anda menyadari seberapa sering logika tersebut digunakan dalam aplikasi. Misalnya, untuk memilih serangkaian pesanan dari daftar.

//  

function Component() {
    const [selected, setSelected] = React.useState()
    const select = React.useCallback(id => setSelected(/** ... */), [
        selected,
        setSelect
    ])

    return <List selectedIds={selected} onSelect={id => select(id)} />
}

//   

const useSelection = () => {
    const [selected, setSelected] = React.useState()
    const select = React.useCallback(id => setSelected(/** ... */), [
        selected,
        setSelect
    ])

    return [selected, select]
}

function Component() {
    const [selected, select] = useSelection()

    return <List selectedIds={selected} onSelect={id => select(id)} />
}

2. Tentang manfaat React.useDebugValue


Hook React.useDebugValue standar mengacu pada fitur Bereaksi yang kurang dikenal. Pengait ini dapat membantu pengembang selama proses debug kode, dapat bermanfaat untuk menggunakannya dalam pengait yang dirancang untuk dibagikan. Ini adalah kait pengguna yang digunakan di banyak komponen aplikasi. Namun, useDebugValuetidak disarankan untuk menggunakannya di semua kait pengguna, karena kait bawaan sudah mencatat nilai debug standar.

Bayangkan membuat pengait khusus yang dirancang untuk membuat keputusan tentang perlunya mengaktifkan beberapa fitur aplikasi. Data status aplikasi yang menjadi dasar keputusan dapat berasal dari berbagai sumber. Mereka dapat disimpan dalam objek konteks Bereaksi, akses yang diatur melalui React.useContext.

Untuk membantu pengembang dalam debugging, saat bekerja dengan alat Bereaksi pengembang, mungkin berguna untuk mengetahui tentang nama bendera yang dianalisis ( flagName) dan varian dari nilai bendera ( flagVariation). Dalam hal ini, menggunakan kait kecil dapat membantu kami React.useDebugValue:

export default function useFeatureToggle(flagName, flagVariation = true) {
    const flags = React.useContext(FlagsContext)
    const isFeatureEnabled = getIsFeatureEnabled(flagName, flagVariation)(flags)

    React.useDebugValue({
        flagName,
        flagVariation,
        isEnabled: isFeatureEnabled
    })

    return isFeatureEnabled
}

Sekarang, bekerja dengan alat pengembang Bereaksi, kita dapat melihat informasi tentang opsi nilai bendera, tentang nama bendera, dan apakah fitur yang menarik bagi kita dihidupkan atau tidak.


Bekerja dengan alat pengembang Bereaksi setelah menerapkan kait React.useDebugValue

Perhatikan bahwa dalam kasus ketika kait pengguna menggunakan kait standar sepertiReact.useStateatauReact.useRef, kait tersebut sudah mencatat status terkait atau data objek ref. Akibatnya, penggunaan konstruksi tampilan di siniReact.useDebugValue({ state })tidak terlalu berguna.

3. Kombinasi dan komposisi kait


Ketika kami mulai menerapkan kait dalam pekerjaan kami dan mulai menggunakan semakin banyak kait dalam komponen, dengan cepat ternyata 5-10 kait dapat hadir dalam komponen yang sama. Dalam hal ini, kait dari berbagai jenis digunakan. Sebagai contoh, kita dapat menggunakan 2-3 kait React.useState, lalu sebuah kait React.useContext(katakanlah, untuk mendapatkan informasi tentang pengguna aktif), sebuah kait React.useEffect, dan juga kait dari perpustakaan lain, seperti react-router atau react-intl .

Di atas diulangi lagi dan lagi, sebagai hasilnya, komponen yang sangat kecil pun tidak begitu kompak. Untuk menghindari hal ini, kami mulai mengekstraksi masing-masing kait ini menjadi kait pengguna, perangkat yang bergantung pada komponen atau kapabilitas aplikasi.

Bayangkan sebuah mekanisme aplikasi yang ditujukan untuk membuat pesanan. Ketika mengembangkan mekanisme ini, banyak komponen yang digunakan, serta kait dari berbagai jenis. Kait ini dapat dikombinasikan sebagai kait khusus, sehingga meningkatkan kegunaan komponen. Berikut adalah contoh menggabungkan satu set kait kecil dalam satu kait.

function OrderCreate() {
    const {
        orderCreater,
        orderFetcher,
        applicationContext,
        goToNextStep,
        pendingOrder,
        updatePendingChanges,
        revertPendingChanges
    } = useOrderCreate()

    return (/** ...children */)
}

4. Perbandingan React.useReducer dan React.useState


Kami sering menggunakan React.useStatekait standar untuk bekerja dengan keadaan komponen. Namun, seiring waktu, keadaan komponen mungkin perlu rumit, yang tergantung pada persyaratan baru untuk komponen tersebut, seperti keberadaan beberapa nilai di negara bagian. Dalam kasus tertentu, penggunaan React.useReducerdapat membantu menghindari kebutuhan untuk menggunakan beberapa nilai dan menyederhanakan logika memperbarui keadaan. Bayangkan manajemen negara ketika membuat permintaan HTTP dan menerima tanggapan. Untuk melakukan ini, Anda mungkin perlu bekerja dengan nilai-nilai seperti isLoading, datadanerror. Sebaliknya, negara dapat dikontrol menggunakan peredam, yang memiliki berbagai tindakan untuk mengelola perubahan keadaan. Pendekatan ini, idealnya, mendorong pengembang untuk memahami keadaan antarmuka dalam bentuk mesin negara.

Peredam yang ditransmisikan React.useReducermirip dengan pereduksi yang digunakan dalam Redux , di mana sistem menerima keadaan saat ini dari tindakan dan harus mengembalikan keadaan berikutnya. Tindakan tersebut berisi informasi tentang jenisnya, serta data yang menjadi dasar pembentukan negara berikutnya. Berikut adalah contoh peredam sederhana yang dirancang untuk mengontrol penghitung tertentu:

const initialState = 0;
const reducer = (state, action) => {
    switch (action) {
        case 'increment': return state + 1;
        case 'decrement': return state - 1;
        case 'reset': return 0;
        default: throw new Error('Unexpected action');
    }
};

Peredam ini dapat diuji secara terpisah dan kemudian digunakan dalam komponen menggunakan React.useReducer:

function Component() {
    const [count, dispatch] = React.useReducer(reducer, initialState);

    return (
        <div>
            {count}
            <button onClick={() => dispatch('increment')}>+1</button>
            <button onClick={() => dispatch('decrement')}>-1</button>
            <button onClick={() => dispatch('reset')}>reset</button>
        </div>
    );
};

Di sini kita dapat menerapkan apa yang kita periksa di tiga bagian sebelumnya, yaitu, kita dapat mengekstraksi semuanya menjadi useCounterReducer. Ini akan meningkatkan kode dengan menyembunyikan informasi jenis tindakan dari komponen yang menjelaskan tampilan elemen antarmuka. Sebagai hasilnya, ini akan membantu mencegah kebocoran detail implementasi ke dalam komponen, dan juga akan memberi kami peluang tambahan untuk kode debug. Inilah yang akan terlihat seperti kait kustom dan komponen yang menggunakannya:

const CounterActionTypes = {
    Increment: 'increment',
    Decrement: 'decrement',
    Reset: 'reset',
}

const useCounterReducer = (initialState) => {
    const [count, dispatch] = React.useReducer(reducer, initialState);

    const increment = React.useCallback(() => dispatch(CounterActionTypes.Increment));
    const decrement = React.useCallback(() => dispatch(CounterActionTypes.Decrement));
    const reset = React.useCallback(() => dispatch(CounterActionTypes.Reset));

    return {
        count,
        increment,
        decrement
    }
}

function Component() {
    const {count, increment} = useCounterReducer(0);

    return (
        <div>
            {count}
            <button onClick={increment}>+1</button>
        </div>
    );
};

5. Implementasi kait secara bertahap


Pada pandangan pertama, gagasan untuk memperkenalkan kait secara bertahap mungkin tampaknya tidak sepenuhnya logis, tetapi di sini saya menyarankan agar mereka yang berpikir demikian mengikuti alasan saya. Seiring waktu, berbagai pola menemukan aplikasi dalam basis kode. Dalam kasus kami, pola-pola ini termasuk komponen orde tinggi, properti rendering, dan sekarang kait. Saat menerjemahkan proyek ke pola baru, pengembang tidak berusaha untuk langsung menulis ulang semua kode, yang, secara umum, hampir mustahil. Akibatnya, Anda perlu mengembangkan rencana untuk mentransfer proyek ke React hooks, yang tidak memberikan perubahan besar pada kode. Tugas ini bisa sangat sulit, karena membuat perubahan pada kode biasanya mengarah pada peningkatan ukuran dan kompleksitasnya. Dengan memperkenalkan kait, kami berusaha menghindari ini.

Basis kode kami menggunakan komponen berbasis kelas dan komponen fungsional. Terlepas dari komponen mana yang digunakan dalam situasi tertentu, kami berusaha membagikan logika melalui React hooks. Pertama, kami menerapkan logika di kait (atau mengulangi implementasi mekanisme tertentu yang ada di dalamnya), kemudian membuat komponen kecil dengan urutan lebih tinggi, di mana kait ini digunakan. Setelah itu, komponen tingkat tinggi ini digunakan untuk membuat komponen berbasis kelas. Akibatnya, kami memiliki logika pembuangan yang terletak di satu tempat, yang dapat digunakan dalam berbagai komponen. Berikut adalah contoh penerapan fungsionalitas kait dalam komponen melalui komponen tingkat tinggi.

export const injectTracking = (propName = 'tracking') => WrappedComponent => {
    const WithTracking = props => {
        const tracking = useTracking();

        const trackingProp = {
            [propName]: tracking,
        };

        return <WrappedComponent {...props} {...trackingProp} />;
    };

    WithTracking.displayName = wrapDisplayName(WrappedComponent, 'withTracking');

    return WithTracking;
};

export default injectTracking;

Ini menunjukkan implementasi fungsionalitas kait useTrackingdalam komponen WrappedComponent. Ngomong-ngomong, ini memungkinkan kami, antara lain, untuk memisahkan tugas-tugas penerapan kait dan penulisan ulang tes di bagian lama sistem. Dengan pendekatan ini, kami masih memiliki mekanisme pembuangan untuk menggunakan kait di semua bagian basis kode.

Ringkasan


Berikut adalah beberapa contoh bagaimana menggunakan React hooks meningkatkan basis kode kami. Kami berharap bahwa kait juga dapat bermanfaat bagi proyek Anda.

Pembaca yang budiman! Apakah Anda menggunakan React hooks?


All Articles