什麼是Hooks?
Hooks是react即將推出的功能,它容許您在不編寫類的狀況下使用狀態和其餘React功能。
個人理解就是能夠用寫無狀態組件的方式去編寫擁有狀態的組件。
遺憾的是,正式版16.7.0出了以後並無hooks,若是須要體驗還需下載next版本,目前是16.7.0-alpha.2前端
npm i react@next 此次與你們分享四個Hooks,我的以爲這幾個應該是以後工做中會常用到的。 1. useState 2. useEffect 3. useReducer 4. useMemo
1.useState
我的感受這個鉤子是重點,使用它便可作到用函數的編寫帶有狀態的組件。react
import React,{ useState,useEffect } from 'react' const HookTest = () => { const [obj,setValue] = useState({key:'count',value:0}); const handleChange = () => { const value = obj.value+1; //改變狀態 setValue(Object.assign(obj,{value})); } return ( <div> {obj.key}:{obj.value} <p> <button onClick={handleChange}>累加</button> </p> </div> ) }
很明顯,重點在於const [obj,setValue] = useState({key:'count',value:0})這一句,useState是個函數,接收一個狀默認值,返回一個數組,第一個元素爲狀態,初始值爲傳入函數的默認值,第二個元素爲方法,可以使用此方法改變狀態的值。git
2.useEffect
這個鉤子,官方所說是componentDidMount,componentDidUpdate和componentWillUnmount這三個生命週期的結合,由於組件掛載完成時會執行,更新時會執行,卸載時會執行,接上面的HookTest組件,往裏添加github
useEffect(()=>{ console.log('obj->',obj); return ()=>{ console.log('卸載時..'); } });
這就是一個基本用法,掛載、更新、卸載都會打印obj對象,return的函數,做爲組件更新或者卸載時執行,好比在使用setinterval,能夠在return的函數裏寫clearinterval。
若是隻想讓它執行一次的話,能夠往函數裏添加第二個參數。npm
useEffect(()=>{ console.log('obj->',obj); },false);
這樣只在掛載完成時執行一次,第二個參數能夠爲false、[]、{}、""
若是想讓他有條件的執行,能夠往第二個參數傳入具體的參數redux
useEffect(()=>{ console.log('obj->',obj); },{obj.value});
若是obj.value值變化時,就執行,沒變化時就不執行,對於性能優化很是友好。數組
3.useReducer性能優化
若是使用過redux的童鞋們不會默認,將須要的狀態保存到一個對象中,可供全部的組件使用。
先上代碼異步
import React, { useReducer,useMemo,useEffect,useState } from 'react'; //建立reducer,reducer可在外部建立而後再引入 function reducer(state = { count: 0 }, action) { switch (action.type) { case 'reset': return { count: 0 }; case 'increment': return { count: state.count + 1 }; case 'decrement': return { count: state.count <= 0 ? 0 : state.count - 1 }; default: return state; } } //組件 const useReducerDemo = () => { const [state, dispatch] = useReducer(reducer, { count: 0 }, { type: 'increment' }); //異步增長 const asyncIncrement = () => { setTimeout(()=>{ dispatch({ type: 'increment' }) },2000); } return ( <div> <p> <span>Count: {state.count}</span> <button onClick={() => dispatch({ type: 'reset' })}>還原</button> <button onClick={() => dispatch({ type: 'increment' })}>+</button> <button onClick={() => dispatch({ type: 'decrement' })}>-</button> <button onClick={asyncIncrement}>async+</button> </p> </div> ) }
能夠看到,和useState很像,也是使用一個數組解構接受返回的值。
先說返回的值:
1.state
天然爲reducer的狀態
2.dispatch
這個是一個函數,有dispatch就意味着咱們能夠不用像使用redux時還須要本身下中間件(如redux-thunk)就能夠進行異步操做,具體看asyncIncrement函數,參數爲一個對象,指定須要執行的action
再說useReducer函數的參數:
第一個參數爲你引入的reducer,第二個參數爲state的默認值,第三個參數爲初始觸發的action,就是載入時默認就執行一個actionasync
4.useMemo
useMemo只有當其中一個輸入發生變化時,纔會從新計算記憶值。此優化有助於避免在每一個渲染上進行昂貴的計算。
此鉤子也是有助於性能優化,接入上面的useReducerDemo組件,往裏添加
const [tips,setTips] = useState(false); //當爲0時提示不能再減了 useEffect(()=>{ if(!state.count){ setTips(true); }else{ setTips(false); } }); const memoizedValue = useMemo(() => { console.log('useMemo run'); return tips }, [tips]);
在return組件元素div裏添加
{ memoizedValue && <p>不能爲負數哦</p> }
以上新增的代碼時爲了實如今reducer裏的count小於等於0或從0變動爲其餘數字時更新true或false,以此達到p元素的顯示與否,不然一直爲上一次計算獲得值,咱們使用了console.log('useMemo run');記錄它更新的次數,當count從0一直+1,只會打印一次'useMemo run',由此說明,只在0變成1的時候執行了一次,日後memoizedValue的值一直爲0變成1時所return的值。
此例子並說明不了什麼,不過當有很龐大計算量的時候就能體現出useMemo的做用了。
useMemo一樣也是一個函數,接受兩個參數,第一個參數爲函數,第二個參數爲要比對的值,返回一個值。
第二個參數裏能夠傳入多個值,如[a,b,c,...],當傳入的這些值有變化時,就會去執行第一個傳入的函數,根據業務需求計算後返回最終結果。
同理,第二個參數傳入的值沒有更新時,不會執行。
結尾
花了一下午的時間體驗hook,其餘的鉤子也使用了個遍,感受這四個在我看來和在我公司業務裏可能會大量的使用到,因此發此文章分享,也爲記錄,本人新手前端一枚,第一次寫文章,有說的不對的地方還請請多多指教。
謝謝你們的閱讀。
以上代碼的github地址爲react-hooks初體驗