React-hooks API介紹

react-hooks HOOKS

  • hooks概念在React Conf 2018被提出來,并將在未來的版本中被引入,hooks遵循函數式編程的理念,主旨是在函數組件中引入類組件中的狀態和生命周期,并且這些狀態和生命周期函數也可以被抽離,實現復用的同時,減少函數組件的復雜性和易用性。
  • 函數組件 (functional component) 內部能夠”鉤住“ React 內部的 state 和 life-cycles。
  • 真正功能強大的地方是使我們能夠更輕松地復用組件邏輯(custom hooks)
  • 讓FunctionalComponent具有ClassComponent的功能

設計Hooks主要是解決ClassComponent的幾個問題:

  • 很難復用邏輯(只能用HOC,或者render props),會導致組件樹層級很深
  • 會產生巨大的組件(指很多代碼必須寫在類里面)
  • 類組件很難理解,比如方法需要bind,this指向不明確
 npm install react@16.7.0-alpha.2
 npm install react-dom@16.7.0-alpha.2

 npm install eslint-plugin-react-hooks@next
    // Your ESLint configuration
    {
    "plugins": [
        // ...
        "react-hooks"
    ],
    "rules": {
        // ...
        "react-hooks/rules-of-hooks": "error"
    }
    }

Hooks API Reference

   ** Basic Hooks **
    useState
    useEffect
    useContext

   ** Additional Hooks **
    useReducer
    useCallback
    useMemo
    useRef
    useImperativeMethods
    useMutationEffect
    useLayoutEffect

Rules of Hooks

  • 只能在頂層調用Hooks 。不要在循環,條件或嵌套函數中調用Hook
  • 只能在functional component中使用

State Hook

定義組件狀態

  • 避免組件的 state 結構過于臃腫,能夠獨立處理每個 state
  • 寫法非常直觀,一眼就可以看出和這個 state 相關的兩個變量
    const useStateExample = () => {
        const [count, setCount] = useState(0);
        const [list, setList] = useState([]);
        const [object, setObject] = useState({ name: 'lishishi', age: 28 });
    }

  • State Hooks的定義必須在函數組件的最高一級,不能在嵌套,循環等語句中使用

  • 一個函數組件可以存在多個State Hooks,并且useState返回的是一個數組,數組的每一個元素是沒有標識信息的,完全依靠調用useState的順序來確定哪個狀態對應于哪個變量,所以必須保證使用useState在函數組件的最外層

  • 最主要的原因就是你不能確保這些條件語句每次執行的次數是一樣的,也就是說如果第一次我們創建了state1 => hook1, state2 => hook2, state3 => hook3這樣的對應關系之后,下一次執行因為something條件沒達成,導致useState(1)沒有執行,那么運行useState(2)的時候,拿到的hook對象是state1的,那么整個邏輯就亂套了,所以這個條件是必須要遵守的!

 const useStateExample = () => {
     if(Math.random() > 1) {
        const [count, setCount] = useState(0);
        const [list, setList] = useState([]);
     }else {
        const [object, setObject] = useState({ name: 'lishishi', age: 28 });
     }
    }

Effect Hook

實現生命周期 (life-cycles)

  • 類似 redux 中的 subscribe,每當 React 因為 state 或是 props 而重新 render 的之后,就會觸發 useEffect 里的這個 callback listener(在第一次 render 和每次 update 后觸發)
  • 在生命周期內做的操作很多都會產生一些 side-effect(副作用)的操作,比如更新 DOM,fetch 數據,等等。
    useEffect(() => {
        //componentDidMount和componentDidUpdate周期的函數體
        return ()=>{ 
        //componentWillUnmount周期的函數體
        }
    })
    // ---------------------
    useEffect(() => {
        //僅在componentDidMount的時候執行
    },[]);
    // -----------------------
    useEffect(() => {
        //僅在componentDidMount的時候執行
        //只有stateName\props.id的值發生改變
    },[stateName,props.id]);
   
    componentDidUpdate(prevProps, prevState) {
        if (prevState.count !== this.state.count) {
        }
         if (prevProps.id !== this.props.id) {
        }
    }

  • useEffect函數必須位于函數組件的最高一級
useState('Mary')           
useEffect(persistForm)    
useState('Poppins')       
useEffect(updateTitle)

Context Hook

替代了 <Context.Consumer> 使用 render props 的寫法,使組件樹更加簡潔。

Reducer Hook

相當于組件自帶的 redux reducer,負責接收 dispatch 分發的 action 并更新 state

配合hooks重新實現react-redux

useReducer + useContext 鉤子上進行一層很簡單的封裝以達到和以往 react-redux \ redux-thunk \ redux-logger 類似的功能

    npm install react-hooks-redux

React.memo() React 16.6.0

  • PureComponent 要依靠 class 才能使用。而 React.memo() 可以和 functional component 一起使用
   const MySnowyComponent = React.memo(function MyComponent(props) {
   // only renders if props have changed!
   });

   // can also be an es6 arrow function
   const OtherSnowy = React.memo(props => {
   return <div>my memoized component</div>;
   });

   // and even shorter with implicit return
   const ImplicitSnowy = React.memo(props => (
   <div>implicit memoized component</div>
   ));

useRef

useCallBack

  • e.g. shouldComponentUpdate ; This is useful when passing callbacks to optimized child components that rely on reference equality to prevent unnecessary renders
const memoizedCallback = useCallback(
 () => {
   doSomething(a, b);
 },
 [a, b],
);

useMemo

  • useMemo will only recompute the memoized value when one of the inputs has changed
  • useCallback(fn, inputs) is equivalent to useMemo(() => fn, inputs)
 const memoizedValue = useMemo(() => computeExpensiveValue(a, b), [a, b]);

useImperativeMethods

  • useImperativeMethods customizes the instance value that is exposed to parent components when using ref
  • useImperativeMethods(ref, createInstance, [inputs])

useMutationEffect useLayoutEffect useEffect 差別

  • useMutationEffect
    It fires synchronously before Layout phase i.e. during the same phase that React performs its DOM mutations. Use it to perform blocking custom DOM mutations without taking any DOM measurement/reading layout.

  • useLayoutEffect
    It fires synchronously after all DOM mutations but before Paint phase. Use this to read layout(styles or layout information) from the DOM and then perform blocking custom DOM mutations based on layout.

  • useEffect
    It runs after the render is committed to the screen i.e. after Layout and Paint phase. Use this whenever possible to avoid blocking visual updates

注意

  • 目前react-hot-loader不能和hooks一起使用

Mixin => HOC => Render Prop => hooks

?著作權歸作者所有,轉載或內容合作請聯系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 227,663評論 6 531
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 98,125評論 3 414
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 175,506評論 0 373
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 62,614評論 1 307
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 71,402評論 6 404
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 54,934評論 1 321
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,021評論 3 440
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,168評論 0 287
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 48,690評論 1 333
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 40,596評論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 42,784評論 1 369
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,288評論 5 357
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,027評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,404評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,662評論 1 280
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,398評論 3 390
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 47,743評論 2 370

推薦閱讀更多精彩內容

  • 作為一個合格的開發者,不要只滿足于編寫了可以運行的代碼。而要了解代碼背后的工作原理;不要只滿足于自己的程序...
    六個周閱讀 8,466評論 1 33
  • 本文將開始詳細分析如何搭建一個React應用架構。 一. 前言 現在已經有很多腳手架工具,如create-reac...
    字節跳動技術團隊閱讀 4,374評論 1 23
  • React.js 小書學習 之 【使用 JSX 描述 UI 信息】 從 JSX 到頁面 過程圖解:JSX 到頁面過...
    zdlucky閱讀 1,287評論 0 20
  • ——任何時候,都要攢足人品,相信愛情。 單身、大齡、博士,還會遇到理想中的愛情嗎?會的。只要做好準備,攢足人品,男...
    Annie_66d0閱讀 395評論 0 0
  • 《我的詩詞》目錄 百萬家庭夜不眠,通宵達亙網波點。 一紙捷報雪霜剪,展翅飛翔新夢燃。
    青梅夢語閱讀 814評論 8 28