學(xué)習(xí)react hook的總結(jié)

react16推出了react hook,react hook使得functional組件擁有了class組件的一些特性阅酪,hook不能用在class 組件里。

React 中提供的 hooks:

  • useState:setState
  • useReducer:setState
  • useRef: ref
  • useContext: context芹助,需配合 createContext 使用
  • useMemo: 可以對 setState 的優(yōu)化
  • useEffect: 類似 componentDidMount/Update, componentWillUnmount也糊,當(dāng)效果為 componentDidMount/Update 時辫封,總是在整個更新周期的最后(頁面渲染完成后)才執(zhí)行
  • useLayoutEffect: 用法與 useEffect 相同砖第,區(qū)別在于該方法的回調(diào)會在數(shù)據(jù)更新完成后荷腊,頁面渲染之前進(jìn)行,該方法會阻礙頁面的渲染
useState
function Counter({ initialCount }) {
  const [count, setCount] = useState(0)
  return (
    <>
      Count: {count}
      <button onClick={() => setCount(0)}>Reset</button>
      <button onClick={() => setCount(prevCount => prevCount + 1)}>+</button>
      <button onClick={() => setCount(prevCount => prevCount - 1)}>-</button>
    </>
  )
}

useState 有一個參數(shù)悄窃,該參數(shù)可傳如任意類型的值或者返回任意類型值的函數(shù)讥电。

useState 返回值為一個數(shù)組,數(shù)組的第一個參數(shù)為我們需要使用的 state轧抗,第二個參數(shù)為一個setter函數(shù)恩敌,可傳任意類型的變量,或者一個接收 state 舊值的函數(shù)横媚,其返回值作為 state 新值纠炮。

useReducer

useReducer 接收三個參數(shù),第一個參數(shù)為一個 reducer 函數(shù)灯蝴,第二個參數(shù)是reducer的初始值恢口,第三個參數(shù)為可選參數(shù),值為一個函數(shù)穷躁,可以用來惰性提供初始狀態(tài)耕肩。這意味著我們可以使用使用一個 init 函數(shù)來計算初始狀態(tài)/值,而不是顯式的提供值问潭。如果初始值可能會不一樣猿诸,這會很方便,最后會用計算的值來代替初始值狡忙。

reducer 接受兩個參數(shù)一個是 state 另一個是 action 梳虽,用法原理和 redux 中的 reducer 一致。

useReducer 返回一個數(shù)組去枷,數(shù)組中包含一個 state 和 dispath怖辆,state 是返回狀態(tài)中的值,而 dispatch 是一個可以發(fā)布事件來更新 state 的函數(shù)删顶。

function init(initialCount) { 
    return {count: initialCount}; 
} 

function reducer(state, action) { 
    switch (action.type) { 
        case 'increment': 
            return {count: state.count + 1}; 
        case 'decrement': 
            return {count: state.count - 1}; 
        case 'reset': 
            return init(action.payload); 
        default: 
            throw new Error(); 
    } 
} 

function Counter({initialCount}) { 
    const [state, dispatch] = useReducer(reducer, initialCount, init); 
    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> 
</> 
); 
} 

function render () { 
    ReactDOM.render(<Counter initialCount={0} />, document.getElementById('root')); 
}

useEffect 和 useLayoutEffect

這個兩個hook差不多只有輕微的執(zhí)行順序上的不同先從useEffect說起吧

useEffect(func, array);

第一個參數(shù)為 effect 函數(shù)竖螃,該函數(shù)將在 componentDidMmount 時觸發(fā)和 componentDidUpdate 時有條件觸發(fā)(該添加為 useEffect 的第二個數(shù)組參數(shù))。同時該 effect 函數(shù)可以返回一個函數(shù)(returnFunction)逗余,returnFunction 將會在 componentWillUnmount 時觸發(fā)在 componentDidUpdate 時先于 effect 有條件觸發(fā)(先執(zhí)行 returnFuncton 再執(zhí)行 effect特咆,比如需要做定時器的清除)注意: 與 componentDidMount 和 componentDidUpdate 不同之處是录粱,effect 函數(shù)觸發(fā)時間為在瀏覽器完成渲染之后腻格。 如果需要在渲染之前觸發(fā),需要使用 useLayoutEffect啥繁。

第二個參數(shù) array 作為有條件觸發(fā)情況時的條件限制:

  • 如果不傳菜职,則每次 componentDidUpdate 時都會先觸發(fā) returnFunction(如果存在),再觸發(fā) effect旗闽。
  • 如果為空數(shù)組[]酬核,componentDidUpdate 時不會觸發(fā) returnFunction 和 effect蜜另。
  • 如果只需要在指定變量變更時觸發(fā) returnFunction 和 effect,將該變量放入數(shù)組嫡意。
useContext

看名字就知道是react里context的hook

const Context = React.createContext('light');
// Provider
class Provider extends Component {
  render() {
    return (
      <Context.Provider value={'dark'}>
        <DeepTree />
      </Context.Provider>
    )
  }
}
// Consumer
function Consumer(props) {
  const context = useContext(Context)
  return (
    <div>
      {context} // dark
    </div>
  )
}
useRef
import { React, useRef } from 'react'
const FocusInput = () => {
  const inputElement = useRef()
  const handleFocusInput = () => {
    inputElement.current.focus()
  }
  return (
    <>
      <input type='text' ref={inputElement} />
      <button onClick={handleFocusInput}>Focus Input</button>
    </>
  )
}
export default FocusInput

與createRef比 举瑰,useRef創(chuàng)建的對象每次都返回一個相同的引用而createRef每次渲染都會返回一個新的引用

useMemo

在沒有hook時我們通常組件優(yōu)化會用到pureComponent 之后又有為函數(shù)設(shè)計的memo方法,通過策略來判斷是否更新蔬螟。

// 使用useMemo
import React, { useState,useMemo, memo } from 'react'

const Child = memo(({ config }) => {
    console.log(config)
    return <div style={{ color:config.color }}>{config.text}</div>
})

function MemoCount() {
    const [count, setCount] = useState(0)
    const [color, setColor] = useState('blue')
    // 只會根據(jù)color的改變來返回不同的對象此迅,否則都會返回同一個引用對象
    const config = useMemo(()=>({
        color,
        text:color
    }),[color])
    
    return (
        <div>
            <button
                onClick={() => {
                    setCount(count + 1)
                }}
                >
                Update Count
            </button>
            <button
                onClick={() => {
                    setColor('green')
                }}
                >
                Update Color
            </button>
            <div>{count}</div>
            <Child config={config} />
        </div>
    )
}

export default MemoCount

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市旧巾,隨后出現(xiàn)的幾起案子耸序,更是在濱河造成了極大的恐慌,老刑警劉巖菠齿,帶你破解...
    沈念sama閱讀 219,188評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件佑吝,死亡現(xiàn)場離奇詭異,居然都是意外死亡绳匀,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,464評論 3 395
  • 文/潘曉璐 我一進(jìn)店門炸客,熙熙樓的掌柜王于貴愁眉苦臉地迎上來疾棵,“玉大人,你說我怎么就攤上這事痹仙∈嵌” “怎么了?”我有些...
    開封第一講書人閱讀 165,562評論 0 356
  • 文/不壞的土叔 我叫張陵开仰,是天一觀的道長拟枚。 經(jīng)常有香客問我,道長众弓,這世上最難降的妖魔是什么恩溅? 我笑而不...
    開封第一講書人閱讀 58,893評論 1 295
  • 正文 為了忘掉前任,我火速辦了婚禮谓娃,結(jié)果婚禮上脚乡,老公的妹妹穿的比我還像新娘。我一直安慰自己滨达,他們只是感情好奶稠,可當(dāng)我...
    茶點故事閱讀 67,917評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著捡遍,像睡著了一般锌订。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上画株,一...
    開封第一講書人閱讀 51,708評論 1 305
  • 那天辆飘,我揣著相機(jī)與錄音涩搓,去河邊找鬼。 笑死劈猪,一個胖子當(dāng)著我的面吹牛昧甘,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播战得,決...
    沈念sama閱讀 40,430評論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼充边,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了常侦?” 一聲冷哼從身側(cè)響起浇冰,我...
    開封第一講書人閱讀 39,342評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎聋亡,沒想到半個月后肘习,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,801評論 1 317
  • 正文 獨居荒郊野嶺守林人離奇死亡坡倔,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,976評論 3 337
  • 正文 我和宋清朗相戀三年漂佩,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片罪塔。...
    茶點故事閱讀 40,115評論 1 351
  • 序言:一個原本活蹦亂跳的男人離奇死亡投蝉,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出征堪,到底是詐尸還是另有隱情瘩缆,我是刑警寧澤,帶...
    沈念sama閱讀 35,804評論 5 346
  • 正文 年R本政府宣布佃蚜,位于F島的核電站庸娱,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏谐算。R本人自食惡果不足惜熟尉,卻給世界環(huán)境...
    茶點故事閱讀 41,458評論 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望氯夷。 院中可真熱鬧臣樱,春花似錦、人聲如沸腮考。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,008評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽踩蔚。三九已至棚放,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間馅闽,已是汗流浹背飘蚯。 一陣腳步聲響...
    開封第一講書人閱讀 33,135評論 1 272
  • 我被黑心中介騙來泰國打工馍迄, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人局骤。 一個月前我還...
    沈念sama閱讀 48,365評論 3 373
  • 正文 我出身青樓攀圈,卻偏偏與公主長得像,于是被迫代替她去往敵國和親峦甩。 傳聞我的和親對象是個殘疾皇子赘来,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,055評論 2 355