React-hooks API介紹

react-hooks HOOKS

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

設(shè)計(jì)Hooks主要是解決ClassComponent的幾個(gè)問題:

  • 很難復(fù)用邏輯(只能用HOC,或者render props),會(huì)導(dǎo)致組件樹層級(jí)很深
  • 會(huì)產(chǎn)生巨大的組件(指很多代碼必須寫在類里面)
  • 類組件很難理解,比如方法需要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

  • 只能在頂層調(diào)用Hooks 。不要在循環(huán),條件或嵌套函數(shù)中調(diào)用Hook
  • 只能在functional component中使用

State Hook

定義組件狀態(tài)

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

  • State Hooks的定義必須在函數(shù)組件的最高一級(jí),不能在嵌套,循環(huán)等語句中使用

  • 一個(gè)函數(shù)組件可以存在多個(gè)State Hooks,并且useState返回的是一個(gè)數(shù)組,數(shù)組的每一個(gè)元素是沒有標(biāo)識(shí)信息的,完全依靠調(diào)用useState的順序來確定哪個(gè)狀態(tài)對(duì)應(yīng)于哪個(gè)變量,所以必須保證使用useState在函數(shù)組件的最外層

  • 最主要的原因就是你不能確保這些條件語句每次執(zhí)行的次數(shù)是一樣的,也就是說如果第一次我們創(chuàng)建了state1 => hook1, state2 => hook2, state3 => hook3這樣的對(duì)應(yīng)關(guān)系之后,下一次執(zhí)行因?yàn)閟omething條件沒達(dá)成,導(dǎo)致useState(1)沒有執(zhí)行,那么運(yùn)行useState(2)的時(shí)候,拿到的hook對(duì)象是state1的,那么整個(gè)邏輯就亂套了,所以這個(gè)條件是必須要遵守的!

 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

實(shí)現(xiàn)生命周期 (life-cycles)

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

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

Context Hook

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

Reducer Hook

相當(dāng)于組件自帶的 redux reducer,負(fù)責(zé)接收 dispatch 分發(fā)的 action 并更新 state

配合hooks重新實(shí)現(xiàn)react-redux

useReducer + useContext 鉤子上進(jìn)行一層很簡單的封裝以達(dá)到和以往 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

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 作為一個(gè)合格的開發(fā)者,不要只滿足于編寫了可以運(yùn)行的代碼。而要了解代碼背后的工作原理;不要只滿足于自己的程序...
    六個(gè)周閱讀 8,664評(píng)論 1 33
  • React.js 小書學(xué)習(xí) 之 【使用 JSX 描述 UI 信息】 從 JSX 到頁面 過程圖解:JSX 到頁面過...
    zdlucky閱讀 1,433評(píng)論 0 20
  • ——任何時(shí)候,都要攢足人品,相信愛情。 單身、大齡、博士,還會(huì)遇到理想中的愛情嗎?會(huì)的。只要做好準(zhǔn)備,攢足人品,男...
    Annie_66d0閱讀 520評(píng)論 0 0
  • 《我的詩詞》目錄 百萬家庭夜不眠,通宵達(dá)亙網(wǎng)波點(diǎn)。 一紙捷報(bào)雪霜剪,展翅飛翔新夢(mèng)燃。
    青梅夢(mèng)語閱讀 861評(píng)論 8 29
  • 我已經(jīng)記不清第一次旅行是什么時(shí)候了,但是我記得每次旅行都是和誰,經(jīng)歷了什么,看見了什么。 記得有次面試被要求寫稿,...
    華麗的曲線閱讀 422評(píng)論 0 5

友情鏈接更多精彩內(nèi)容