1. 什么是hooks
A way to use state and other React features without writing a class.
React Hooks是React從v16.8引入的一種新的更簡單更方便的編寫組件的功能拧晕。hooks提供了一種可以不用寫class而直接使用state和其他React特性的能力,而且自定義hooks可以將公共邏輯抽離,使之可以在多個組件之間共享蛔翅。
2. hooks的由來
hooks
主要是為了解決以下3個React問題
組件帶狀態(tài)變得難以復用
復雜邏輯不用跟隨生命周期
-
解決難以理解的class
js中的this取值跟其他面向對象語言都不同赘来,是在運行時決定的麸祷。為了解決這一痛點仅父,才有了箭頭函數(shù)的this綁定特性用含。另外何時使用class component 和 function component也是一件容易糾結的事离咐,對于優(yōu)化方面來說谱俭,class component在預編譯和壓縮方面也比普通函數(shù)困難得多,還容易出錯宵蛀。
3. 使用
-
state hook
import { useState } from 'react' function Demo() { const [count, setCount] = useState(0) return ( <div> <p>count: { count }</p> <button onClick={() => { setCount(count + 1) }}>點擊</button> </div> ) }
useState
只有一個參數(shù)昆著,即count的初始值,可以是任意類型糖埋。如果count是對象宣吱,useState
不會像setState
自動合并原state
,可以:setState(preV => { return { ...preV, ...updateV } // Object.assign(preV, updateV) })
多個
state
變量只需要多次調用useState
即可... function Demo2() { const [count, setCount] = useState(0) const [fruit, setFruit] = useState('apple') ... }
-
Effect hook
我們希望組件在DOM掛載和更新后執(zhí)行相同的操作瞳别,使用React Effect hooks寫法:
import React, { useEffect } from 'react' function Demo3() { const [count, setCount] = useState(0) useEffect(() => { document.title = `clicked ${count} times` }) }
傳統(tǒng)class component寫法:
import React from 'react' class Demo3 extends React.Component{ constrctor(props) { super(props) this.state = { count: 0 } } componentDidMount () { document.title = `clicked ${this.state.count} times` } compoenntDidUpdate () { document.title = `clicked ${this.state.count} times` } ... }
傳統(tǒng)class component征候,我們需要在兩個生命周期中調用相同的函數(shù),使用Effect特性React會保存?zhèn)鬟f的函數(shù)祟敛,并在DOM渲染后調用該函數(shù)疤坝。
useEffect
同時擁有componentDidMount
,componentDidUpdate
,componentWillUnmount
三個生命周期的執(zhí)行時機。但Effct并不會阻塞瀏覽的渲染馆铁,使應用看起來更加流暢跑揉。有時候我們?yōu)榱朔乐箖却嫘孤┬枰宄腅ffct,class component中需要在
componentDIdMount
中注冊并在componentWillUnmount
中銷毀,使用hooks只需要在useEffct
中返回一個函數(shù)即可function Demo4() { useEffct(() => { let timer = setInterval(() => { console.log(1) }) return () => { clearInterval(timer) } }) }
當
useEffct
返回一個函數(shù)的時候历谍,React會在下一次執(zhí)行副作用之前調用一次清理函數(shù)现拒。組件掛載 —> 執(zhí)行副作用 —>組件更新 —>執(zhí)行清理函數(shù)—>執(zhí)行副作用—>組件更新—>執(zhí)行清理函數(shù)—>組件卸載
所以每次
state
更新我們都會重新渲染一次,如果state
值沒有改變的情況下(原來count是5改變后還是5)望侈,我們不想調用Effct印蔬,只需要在useEffct
函數(shù)中傳入第二個參數(shù)[count]
即可。React會對前一次渲染的[5]和后一次渲染的[5]對比脱衙,數(shù)組內元素全部相等侥猬,React就會跳過這個Effct,同時實現(xiàn)了性能的優(yōu)化捐韩。該參數(shù)為數(shù)組退唠,可以傳多個數(shù)組,一般會將Effct用到的props
和state
都傳進去荤胁。清除函數(shù)同理瞧预。如果
useEffct
傳入的第二個參數(shù)是一個[]
,等效于componentDidMount
和componentWillUnmount
4. hooks規(guī)則
只能在
React 函數(shù)式組件
中調用Hook只能在
函數(shù)
最外層調用Hook只能用在
函數(shù)
最頂層不能用在循環(huán)寨蹋、條件判斷語句松蒜,嵌套函數(shù)
ESLint插件
eslint-plugin-react-hooks
格式規(guī)范
...