
Dengan dirilisnya React 16.6.0 baru, HOOKS (PROPOSAL) muncul di dokumentasi. Mereka sekarang tersedia di react 17.0.0-alpha dan dibahas dalam RFC terbuka : React Hooks . Mari kita lihat apa itu dan mengapa dibutuhkan di bawah potongan.
Ya itu adalah RFC dan Anda dapat memengaruhi implementasi akhir yang membahas dengan para pembuat reaksi mengapa mereka memilih pendekatan ini atau itu.
Mari kita lihat seperti apa bentuk kait standar:
import { useState } from 'react'; function Example() {
Cobalah untuk berpikir tentang kode ini, ini adalah penggoda dan pada akhir artikel Anda sudah mengerti apa artinya. Hal pertama yang harus Anda ketahui adalah bahwa ini tidak merusak kompatibilitas ke belakang dan mungkin mereka akan ditambahkan dalam 16.7 setelah mengumpulkan umpan balik dan saran di RFC.
Seperti yang orang-orang jamin, ini bukan rencana untuk memotong kelas dari reagen.
Juga, kait tidak menggantikan konsep reaksi saat ini, semuanya ada di tempat alat peraga / negara / konteks / referensi. Ini hanyalah cara lain untuk menggunakan kekuatan mereka.
Motivasi
Sekilas, Hooks memecahkan masalah yang tidak terhubung yang muncul dengan dukungan puluhan ribu komponen selama 5 tahun dari facebook.
Hal yang paling sulit adalah menggunakan kembali logika dalam komponen stateful, reaksi tidak memiliki cara untuk melampirkan perilaku yang dapat digunakan kembali ke komponen (misalnya, hubungkan ke repositori). Jika Anda bekerja dengan Bereaksi, Anda tahu konsep HOC (komponen orde tinggi) atau render props. Ini adalah pola yang cukup baik, tetapi kadang-kadang mereka digunakan secara berlebihan, mereka memerlukan restrukturisasi komponen sehingga mereka dapat digunakan, yang biasanya membuat kode lebih rumit. Perlu melihat aplikasi reaksi yang khas dan akan menjadi jelas apa yang dipertaruhkan.

Ini disebut neraka terbungkus - neraka pembungkus.
Aplikasi dari HOC saja normal dalam realitas saat ini, mereka menghubungkan komponen ke toko / tema / lokalisasi / custom hock, saya pikir semua orang tahu ini.
Menjadi jelas bahwa reaksi memerlukan mekanisme primitif lain untuk memisahkan logika.
Dengan menggunakan pengait, kita dapat mengekstrak status komponen sehingga dapat diuji dan digunakan kembali. Hook memungkinkan Anda untuk menggunakan kembali state logic tanpa mengubah hierarki komponen. Ini memfasilitasi pertukaran tautan antara banyak komponen atau keseluruhan sistem. Juga, komponen kelas terlihat sangat menakutkan, kami menggambarkan metode siklus hidup dari componentDidMount
/ shouldComponentUpdate
/ componentDidUpdate
, keadaan komponen, membuat metode untuk bekerja dengan keadaan / sisi, mengikat metode untuk instance komponen, dan sehingga dapat terus dan terus. Biasanya, komponen seperti itu melampaui garis x, di mana x cukup sulit untuk dipahami.
Kait memungkinkan Anda melakukan hal yang sama dengan memecah logika antar komponen menjadi fungsi-fungsi kecil dan menggunakannya di dalam komponen.
Kelas sulit untuk orang dan untuk mobil
Dalam mengamati kelas facebook adalah hambatan besar ketika belajar Bereaksi. Anda perlu memahami cara kerjanya, dan tidak bekerja seperti pada bahasa pemrograman lain, Anda juga harus ingat tentang pengikatan acara yang mengikat. Tanpa kalimat sintaks yang stabil, kode tersebut terlihat sangat bertele-tele. Orang-orang memahami alat peraga / pola keadaan dan apa yang disebut aliran data top-down, tetapi kelasnya cukup sulit untuk dipahami.
Terutama jika tidak terbatas pada templat, belum lama ini orang-orang dari reaksi bereksperimen dengan tata letak komponen dengan Prepack dan melihat hasil yang menjanjikan, namun demikian, komponen kelas memungkinkan Anda untuk membuat pola buruk yang tidak diinginkan yang membuat optimisasi ini menghilang, kelas juga tidak bermigrasi dengan sangat baik ketika Kelas ulang panas membuatnya tidak bisa diandalkan. Pertama-tama, orang-orang ingin memberikan API yang mendukung semua optimasi dan berfungsi dengan baik dengan reboot panas.
Lihatlah kaitnya
Kait negara
Kode di bawah ini membuat paragraf dan tombol, dan jika kita klik tombol, nilai dalam paragraf akan bertambah.
import { useState } from 'react'; function Example() {
Dari sini kita dapat menyimpulkan bahwa kait ini bekerja sama dengan konsep seperti state
.
Metode useState
sedikit lebih terperinci mengambil satu argumen, ini adalah nilai default dan mengembalikan sebuah tuple di mana ada nilai itu sendiri dan metode untuk mengubahnya, tidak seperti setState, setCount tidak akan melakukan penggabungan nilai, tetapi hanya memperbaruinya. Kami juga dapat menggunakan beberapa pernyataan negara, misalnya:
function ExampleWithManyStates() {
Karenanya, kami membuat beberapa status sekaligus dan kami tidak perlu memikirkan cara menguraikannya. Dengan demikian, dapat dibedakan bahwa kait adalah fungsi yang memungkinkan Anda untuk "terhubung" ke chip komponen kelas, sama seperti kait tidak berfungsi di dalam kelas, ini penting untuk diingat.
Pengait efek
Seringkali dalam komponen kelas, kami membuat fungsi efek samping, misalnya, berlangganan acara atau membuat permintaan data, biasanya untuk ini kami menggunakan metode componentDidUpdate
/ componentDidUpdate
import { useState, useEffect } from 'react'; function Example() { const [count, setCount] = useState(0);
Ketika kami memanggil useEffect
kami memberi tahu reaksi untuk melakukan 'efek samping' setelah memperbarui perubahan di pohon DOM. Efek dinyatakan di dalam komponen, oleh karena itu mereka memiliki akses ke alat peraga / negara. Dan kita dapat membuatnya dengan cara yang persis sama seperti yang kita suka.
function FriendStatusWithCounter(props) { const [count, setCount] = useState(0); useEffect(() => { document.title = `You clicked ${count} times`; }); const [isOnline, setIsOnline] = useState(null); useEffect(() => { ChatAPI.subscribeToFriendStatus(props.friend.id, handleStatusChange); return () => { ChatAPI.unsubscribeFromFriendStatus(props.friend.id, handleStatusChange); }; }); function handleStatusChange(status) { setIsOnline(status.isOnline); }
Segera perlu memperhatikan efek samping kedua di dalamnya, kami mengembalikan fungsi, kami melakukan ini untuk melakukan beberapa tindakan setelah komponen melakukan unmount, dalam api baru ini disebut efek dengan pembersihan. Efek lain dapat mengembalikan apa pun.
Aturan kait
Hooks hanyalah fungsi javascript, tetapi mereka hanya membutuhkan dua aturan:
- Kait harus dilakukan di bagian paling atas dari hierarki fungsi (ini berarti Anda tidak boleh memanggil kait dalam kondisi dan loop, jika reaksi tidak dapat menjamin urutan pelaksanaan kait)
- Kait panggilan hanya di Bereaksi fungsi atau komponen fungsional atau kait panggilan dari kait kustom (ini di bawah).
Untuk mengikuti aturan ini, orang-orang dari tim reaksi membuat plugin linter yang akan menimbulkan kesalahan jika Anda memanggil hook di komponen kelas atau dalam loop dan kondisi.
Kait kustom
Pada saat yang sama, kami ingin menggunakan kembali logika komponen stateful, biasanya HOC atau render props pola digunakan untuk ini, tetapi mereka membuat volume tambahan dari aplikasi kami.
Sebagai contoh, kami menjelaskan fungsi berikut:
import { useState, useEffect } from 'react'; function useFriendStatus(friendID) { const [isOnline, setIsOnline] = useState(null); function handleStatusChange(status) { setIsOnline(status.isOnline); } useEffect(() => { ChatAPI.subscribeToFriendStatus(friendID, handleStatusChange); return () => { ChatAPI.unsubscribeFromFriendStatus(friendID, handleStatusChange); }; }); return isOnline; }
Menyadari kode ini, itu akan menjadi pengait kustom yang dapat kita panggil dalam berbagai komponen. Misalnya, seperti ini:
function FriendStatus(props) { const isOnline = useFriendStatus(props.friend.id); if (isOnline === null) { return 'Loading...'; } return isOnline ? 'Online' : 'Offline'; }
atau lebih
function FriendListItem(props) { const isOnline = useFriendStatus(props.friend.id); return ( <li style={{ color: isOnline ? 'green' : 'black' }}> {props.friend.name} </li> ); }
Bagaimanapun, kami menggunakan kembali status komponen, setiap panggilan ke fungsi useFriendStatus
menciptakan keadaan terisolasi. Perlu juga dicatat bahwa awal dari fungsi ini dimulai dengan penggunaan kata, yang berarti bahwa itu adalah hook. Kami menyarankan Anda mengikuti format ini. Anda dapat menulis kait khusus untuk apa saja, animasi / langganan / pengatur waktu dan banyak lagi.
Ada beberapa kait lagi.
useContext
useContext
memungkinkan Anda untuk menggunakan nilai pengembalian yang biasa alih-alih renderProps, konteks yang ingin kami ambil ke dalamnya dan itu akan mengembalikannya kepada kami, sehingga kami dapat menyingkirkan semua HOC yang meneruskan konteks ke alat peraga.
function Example() { const locale = useContext(LocaleContext); const theme = useContext(ThemeContext);
Dan sekarang kita bisa menggunakan objek konteks dalam nilai balik.
useCallback
const memoizedCallback = useCallback( () => { doSomething(a, b); }, [a, b], );
Seberapa sering Anda harus membuat komponen kelas hanya untuk menyimpan referensi ke suatu metode? Ini tidak perlu dilakukan lagi, kita bisa menggunakan useCallback dan komponen kita tidak akan digambar ulang karena tautan baru ke onClick telah tiba.
gunakanMemo
Kami mengembalikan nilai memized, nilai memized berarti itu dihitung hanya ketika salah satu argumen telah berubah, kedua kalinya hal yang sama tidak akan dihitung.
const memoizedValue = useMemo(() => computeExpensiveValue(a, b), [a, b]);
Ya, di sini Anda harus menduplikasi nilai dalam array sehingga hook mengerti bahwa mereka tidak berubah.
useRef
useRef
mengembalikan nilai yang dimutasi, di mana bidang .current
akan diinisialisasi dengan argumen pertama, objek akan ada selama komponen ada.
Contoh paling umum ketika berfokus pada input
function TextInputWithFocusButton() { const inputEl = useRef(null); const onButtonClick = () => {
gunakanMeterativeMethods
useImperativeMethods
mengkustomisasi nilai instance yang dilewatkan dari induk dan menggunakan ref secara langsung. Seperti biasa, tautan langsung harus dihindari dan forwardRef
harus digunakan
function FancyInput(props, ref) { const inputRef = useRef(); useImperativeMethods(ref, () => ({ focus: () => { inputRef.current.focus(); } })); return <input ref={inputRef} ... />; } FancyInput = forwardRef(FancyInput);
Dalam contoh ini, komponen yang FancyInput
dapat memanggil fancyInputRef.current.focus()
.
gunakanMutationEffect
useMutationEffect
sangat mirip dengan useEffect
kecuali bahwa itu dimulai secara sinkron pada tahap ketika reaksi mengubah nilai DOM sebelum komponen tetangga diperbarui, kait ini harus digunakan untuk melakukan mutasi DOM.
Lebih baik untuk memilih menggunakan Efek untuk mencegah pemblokiran perubahan visual.
useLayoutEffect
useLayoutEffect
mirip dengan useEffect
kecuali bahwa itu berjalan secara sinkron setelah semua pembaruan DOM dan rendering ulang secara sinkron. Pembaruan yang direncanakan di useLayoutEffect
diterapkan secara serempak sebelum browser dapat menggambar elemen. Anda juga harus mencoba menggunakan efek useEffect
standar agar tidak memblokir perubahan visual.
useReducer
useReducer
adalah pengait untuk membuat peredam yang mengembalikan status dan kemampuan untuk mengirim perubahan:
const [state, dispatch] = useReducer(reducer, initialState);
Jika Anda memahami cara kerja Redux, maka Anda memahami cara kerja useReducer
. Contoh yang sama dengan penghitung di atas hanya melalui useReducer
:
const initialState = {count: 0}; function reducer(state, action) { switch (action.type) { case 'reset': return initialState; case 'increment': return {count: state.count + 1}; case 'decrement': return {count: state.count - 1}; } } function Counter({initialCount}) { const [state, dispatch] = useReducer(reducer, initialState); return ( <> Count: {state.count} <button onClick={() => dispatch({type: 'reset'})}> Reset </button> <button onClick={() => dispatch({type: 'increment'})}>+</button> <button onClick={() => dispatch({type: 'decrement'})}>-</button> </> ); }
UseReducer juga membutuhkan 3 argumen, ini adalah action
yang harus dijalankan ketika reducer diinisialisasi:
const initialState = {count: 0}; function reducer(state, action) { switch (action.type) { case 'reset': return {count: action.payload}; case 'increment': return {count: state.count + 1}; case 'decrement': return {count: state.count - 1}; } } function Counter({initialCount}) { const [state, dispatch] = useReducer( reducer, initialState, {type: 'reset', payload: initialCount}, ); return ( <> Count: {state.count} <button onClick={() => dispatch({type: 'reset', payload: initialCount})}> Reset </button> <button onClick={() => dispatch({type: 'increment'})}>+</button> <button onClick={() => dispatch({type: 'decrement'})}>-</button> </> ); }
Kami juga dapat membuat konteks dalam peredam ini dan menggunakannya melalui hook useContext
menggunakannya di seluruh aplikasi, ini tetap untuk pekerjaan rumah.
Untuk meringkas
Hooks adalah pendekatan yang cukup kuat untuk menyelesaikan wrapper-hell dan menyelesaikan beberapa masalah, tetapi semuanya dapat digunakan dengan satu definisi transfer tautan . Sudah mulai tampak koleksi kait untuk digunakan atau koleksi ini . Anda dapat mempelajari lebih lanjut tentang pengait di dokumentasi .