React Hooks 深入系列

2022-03-26 16:34:39 字數 3398 閱讀 5734

本文基於近段時間對 hooks 碎片化的理解作一次簡單梳理, 個人部落格。同時歡迎關注基於 hooks 構建的 ui 元件庫 —— snake-design。

在 class 已經融入 react 生態的節點下, react 推出的 hooks 具有如下優勢:

寫出 useeffect 的所用到的依賴

在以下 demo 中,useeffect的第二個引數傳入, 希望的是useeffect裡的函式只執行一次(類似在componentdidmount中執行一次, 但是注意這裡僅僅是類似, 詳細原因見上一條注意項), 頁面上每隔 1s 遞增 1。

function demo() , 1000);

return () => ;

}, );

return count;

}

但這樣達到我們預期的效果了麼? demo, 可以看到介面上只增加到 1 就停止了。原因就是傳入的第二個引數搞的鬼,表示沒有外界狀態對effect產生干擾。流程大致如下:

第一次呼叫useeffect傳入的count為 0, 於是setcount(0 + 1);

useeffect第二個引數的影響,count仍然為 0, 所以相當於還是setcount(0 + 1);

那如何修正上述問題呢? 方法有兩個(方法一為主, 方法二為輔):

不過遇到setcount(count => count + 1)的情況就可以考慮使用usereducer了。

何時使用 usereducer

使用usestate的地方都能用usereducer進行替代。相較usestate,usereducer有如下優勢:

處理 useeffect 中的公用函式

function demo() `

} useeffect(() => , [getfetchurl]);

useeffect(() => , [getfetchurl]);

return count;

}

此時useeffect中傳入的第二個引數getfetchurl相當於每次都是新的, 所以每次都會請求資料, 那除了[getfetchurl]將改為這種不推薦的寫法外,有兩種解決方法:

*. 方法一: 提公升getfetchurl的作用域;

*. 方法二: 使用usecallback或者usememo來包裹 getfetchurl;

react.memo修飾乙個函式元件,usememo修飾乙個函式。它們本質都是運用快取。

為了理解 react hooks 內部實現原理, 對usestateuseeffect進行了簡單的實現。

usestate 的簡單實現

使用閉包來實現usestate的簡單邏輯:

// 這裡使用閉包

const react = (function()

return [_val, setval]

}}})()

測試如下:

function counter() 

}counter().render() // 0

counter().click() // 模擬點選

counter().render() // 1

useeffect 的簡單實現
var react = (function() 

return [_val, setval]

},useeffect(callback, deps)

}}})()

測試**如下:

var  = react

function counter() , [count])

return

}counter().render() // 'useeffect' 0, 'render', 0

counter().noop()

counter().render() // 'render', 0

counter().click()

counter().render() // 'useeffect' 1, 'render', 1

處理多次呼叫的情形

為了在hooks中能使用多次usestate,useeffect, 將各個usestate,useeffect的呼叫存進乙個陣列中, 在上面基礎上進行如下改造:

const react = (function() ,

usestate(initialvalue)

return [hooks[currenthook++], setval]

},useeffect(callback, deps)

}}})()

測試**如下:

var  = react

function counter() , [count, type])

return

}/* 如下 mock 執行了 useeffect、render; 這裡使用 react.render 的原因是為了重置 currenthook 的值 */

let comp = react.render(counter) // useeffect 0 type hi render 0

/* 如下 mock 只執行了 render */

comp.noop()

comp = react.render(counter) // render 0

/* 如下 mock 重新執行了 useeffect、render */

comp.click()

react.render(counter) // useeffect 1, render 1

React Hooks 初步嘗試

1.usestate 返回乙個 state,以及更新 state 的函式。const state,setstate usestate initialstate 如果初始 state 需要通過複雜計算獲得,則可以傳入乙個函式,在函式中計算並返回初始的 state,此函式只在初始渲染時被呼叫 const...

react hooks 實戰練習

在class中,我們是通過建構函式中,設定state的 this.state 在函式中,沒有this,所以之前的this都不能分配和讀取了,然後在hook中用到了usestate import react,from react 先引入usestate const customeraccess pro...

React,Hooks中useContext的使用

之前在class元件裡面,有乙個context還好,但是多個的話我們就要進行無限巢狀,特別麻煩 在hooks中如何使用呢?首先建立乙個home.js 父元件 這裡定義兩個context來展示效果 import memodemotwo from 子元件 export const usercontext...