Reactv16.7″Hooks”-WhattoExpect
什麼是 Hooks?
Hooks 是一個 React 函式元件內一類特殊的函式(通常以 “use” 開頭,比如 “useState”),使開發者能夠在 function component 裡依舊使用 state 和 life-cycles,以及使用 custom hook 複用業務邏輯。
動機
在 React 裡,function component 就是一個 pure render component,沒有 state 和 component life-cycle。如果需要這兩個中的任意一個,就需要變成 class component。在既有的 React API 下,這個模式有如下一些缺點:
元件間交流的耦合度很高,元件樹臃腫
在既有的模式下,React 的元件間通訊無非是兩種,一種是單項資料流,另一種是通過 redux 之類的 global store 來實現全域性狀態和各元件間的解耦。當有些狀態不適合放在 global store 的情況下,元件間邏輯的複用和溝通就變得十分困難(必須一層一層往下傳)。這一點在 Higher order component (高階元件) 和 render props 中尤其常見。我們為了複用一些邏輯,單獨創造了很多 HOC(高階元件) 來向下傳遞狀態。這導致的問題就是當我們的應用規模變得越來越大的時候,一些無關 UI 的 wrapper 元件越來越多,React 元件樹變得越來越臃腫(在 devtool 中可以甚至看到數十層 wrapper)。某些業務場景下,一個 Tooltip component 裡面都巢狀了三四層額外的元件,使開發和除錯的效率變得很低。
在新的 React hook 中,我們可以建立 custom hook,在其中複用一些邏輯,這些邏輯不再出現在元件樹中,而是成為一個單獨的,獨立的邏輯單元,但是他們仍然響應 React 在渲染之間的變化。
JavaScript 的 class 產生的諸多疑惑
這一點是相對於 JavaScript 來說的。還記得剛入門 JavaScript 的時候,需要跨越的一個重要難關就是 ”this” 指向,以及原型鏈,繼承這些問題。即使我們真正覺得明白了其中的原理,在日常的開發中也難免因為疏忽而踩坑,這一系列的問題導致新手相對比較難上手 React。舉個簡單的例子,React 元件內的 event listener 之前需要手動 bind this 的問題,這個問題就很難對一個 JavaScript 入門的新手解釋明白。
而這一系列的問題,將在 Hook 中被極大地解決。如果沒有 class,沒有了 this,可能上述的種種問題都不再是問題了。
Write Hooks
說了這麼多,Hooks API 是什麼樣呢?首先需要宣告的是,Hooks 是向後相容的,class component 不會被移除。作為開發者,可以慢慢遷移到這個新的 API。
Hooks 主要分為三種:
● State hooks (在 function component 中使用 state)
● Effect hooks (在 function component 中使用生命週期和 side effect)
● Custom hooks (自定義 hooks 用來複用元件邏輯,解決了上述的第一個動機中闡述的問題,這一部分就不在此多費篇幅介紹了,請大家移步文件)。
State hooks
import { useState } from `react`;
function Example() {
// Declare a new state variable, which we`ll call "count"
const [count, setCount] = useState(0);
return (
<div>
<p>You clicked {count} times</p>
<button onClick={() => setCount(count + 1)}>
Click me
</button>
</div>
);
}
之前講過 hook 本質是一個特殊的函式(通常以 “use” 開頭)。在這裡,”useState” 就是一個 hook,通過它我們能夠嵌入元件內部的 state。這個函式返回一個 pair,第一個值是當前對應這個 hook 的 state 值,第二個是怎樣更新這個值。
我們可以從中感覺到,這兩個返回值分別對應的以前的用法是:
● this.state
● this.setState
除此之外,我們還可以在一個函式元件中使用多個 useState:
function ExampleWithManyStates() {
// Declare multiple state variables!
const [age, setAge] = useState(42);
const [fruit, setFruit] = useState(`banana`);
const [todos, setTodos] = useState([{ text: `Learn Hooks` }]);
// ...
}
這給我們的一個非常大的好處就是我們能夠避免元件的 state 結構過於臃腫(因為之前每個 component class 只能有一個 state),能夠獨立處理每個 state。另一個好處就是這種寫法非常直觀,一眼就可以看出和這個 state 相關的兩個變數,比如 [age, setAge]。
Effect hooks
import { useState, useEffect } from `react`;
function Example() {
const [count, setCount] = useState(0);
// Similar to componentDidMount and componentDidUpdate:
useEffect(() => {
// Update the document title using the browser API
document.title = `You clicked ${count} times`;
});
return (
<div>
<p>You clicked {count} times</p>
<button onClick={() => setCount(count + 1)}>
Click me
</button>
</div>
);
}
我們還需要解決一個問題,那就是怎樣在 function component 裡使用 life-cycles,生命週期函式。在這裡,所有的 life-cycles,比如 componentDidMount, componentDidUpdate, shouldUpdate, 等等都集合成一個 Hook,叫做 useEffect。這個函式類似 redux 中的 subscribe,每當 React 因為 state 或是 props 而重新 render 的之後,就會觸發 useEffect 裡的這個 callback listener(在第一次 render 和每次 update 後觸發)。
為什麼叫 useEffect 呢?因為我們通常在生命週期內做的操作很多都會產生一些 side-effect(副作用)的操作,比如更新 DOM,fetch 資料,等等。
Other Built-in Hooks
除了 useState, useEffect 還有另外一些 React 自帶的 hooks。比如:
● useContext
替代了 <Context.Consumer> 使用 render props 的寫法,使元件樹更加簡潔。
● useReducer
相當於元件自帶的 redux reducer,負責接收 dispatch 分發的 action 並更新 state。
詳細用法請看文件。
總結
讀到這裡,你可能理解了為什麼這個新的 API 被叫做 “Hooks” 了。”Hooks” 本意是”鉤子“的意思。在 React 裡,hooks 就是一系列特殊的函式,使函式元件 (functional component) 內部能夠”鉤住“ React 內部的 state 和 life-cycles。
這個向後相容的 API 在解決了一些既有問題的情況下,不僅使我們能夠更好地使用 state 和 life-cycles,真正功能強大的地方是使我們能夠更輕鬆地複用元件邏輯(custom hooks)。但是限於篇幅,很多功能強大的部分和一些注意事項在這篇文章裡並沒有過多講解,請大家移步官方文件學習更詳細的姿勢(牆裂推薦)。
原文釋出時間為:2018-11-02
本文作者:cyan
本文來自雲棲社群合作伙伴“前端大學”,瞭解相關資訊可以關注“前端大學”。
相關文章
- Reactv16.7:沒錯,我們跳票了React
- hooksHook
- [react] hooksReactHook
- Redux with HooksReduxHook
- React HooksReactHook
- React Hooks (Proposal)ReactHook
- 探React HooksReactHook
- 理解 React HooksReactHook
- Render Props and HooksHook
- Why React HooksReactHook
- React Hooks 梳理ReactHook
- React Hooks 指北ReactHook
- React Hooks 札記ReactHook
- [譯] 理解 React HooksReactHook
- React Hooks 的用法ReactHook
- 精讀《React Hooks》ReactHook
- Hooks概覽(譯)Hook
- React hooks實踐ReactHook
- 淺談React HooksReactHook
- React Hooks總結ReactHook
- 實現 React HooksReactHook
- React Hooks 深入系列ReactHook
- 擁抱 React HooksReactHook
- Hooks中的useStateHook
- react之react HooksReactHook
- React Hooks的理解ReactHook
- React State Hooks的閉包陷阱,在使用Hooks之前必須掌握ReactHook
- ?一個簡單愉悅的 hooks 使用庫 react-hooks-easyHookReact
- react hooks初體驗ReactHook
- ReactJs的Hooks簡介ReactJSHook
- 淺談 React Hooks(二)ReactHook
- React Hooks 實用指南ReactHook
- React Hooks 使用詳解ReactHook
- 初探React Hooks & SSR改造ReactHook
- React Hooks-概覽ReactHook
- 淺談 React Hooks(一)ReactHook
- ts + hooks 的基本使用Hook
- React — 通用hooks封裝ReactHook封裝