React Hooks , 此次必定會!

Hooks解決了什麼問題

類組件

複用問題

  1. 雖然有狀態,可是若要複用邏輯狀態麻煩
  2. 即便用高階組件逃脫不出添加最外部的父組件來控制

生命週期及其內存

  1. 每次組件render時都帶有其狀態、函數、變量
  2. 如有些組件中含有像定時器等則須要在組件掛載時添加,組件卸載時清除,相同邏輯的函數要分散在生命週期中,難以進行控制

State控制問題

  1. 對狀態的操做頻繁且分散

this的綁定問題

  1. 父組件給子組件傳遞函數時,必須綁定 this
//方法一:
constructor(props) {  this.handleClickBind = this.handleClick.bind(this); }  //使用時:在props不變時button不刷新 <button onClick={this.handleClickBind}></button>  //方法二:因爲bind返回一個新函數,因此不管props是否變化始終刷新 <button onClick={this.handleClick.bind(this)}></button>  //方法三:用箭頭函數穿透,與方法二相似每次都刷新 <button onClick={()=>this.handleClick()}></button> 複製代碼

函數組件

沒有State

沒有生命週期

👍Hooks的優點

  • 抽離狀態層方便複用邏輯
  • 相關聯函數鏈接更加緊密
  • effect的分離
    1. 某些生命週期與渲染衝突影響用戶體驗
    2. 分離使其不影響渲染
  • 徹底使用函數組件解決全部問題

👏Hooks開衝

  • useState
  • useEffect
  • useContext
  • useReducer
  • useCallback
  • useMemo
  • useRef
  • useImperativeHandle
  • useLayoutEffect
  • useDebugValue

useState

🔔第一步:讓函數組件擁有stateweb

const [state,setState]=useState({...initialState})
複製代碼
  • 返回的state爲最新狀態,setState爲更新函數
  • setState的更新爲直接替換而非合併
  • 修改狀態值,試圖也會同時更新

useEffect

🔔第二步:讓函數組件擁有生命週期數組

useEffect(() => {
 fn()  return unfn() },[controlparams]) 複製代碼

使用時請注意:緩存

  • useEffect 就是監聽每當依賴變化時,執行回調函數的存在函數組件中的鉤子函數。
  • effect在render後按照先後順序執行。
  • effect在沒有任何依賴的狀況下,render後每次都按照順序執行。
  • 能夠把 useEffect Hook 看作 componentDidMount,componentDidUpdate 和 componentWillUnmount 這三個函數的組合。
  • fn()組件掛載時執行,unfn用於卸載時的清除操做
  • 防止頻繁操做時 每次render都是獨立的,裏面有獨立的state、effects、function積累消耗性能
  • 可能有時候內部的內容並無發生變化,這時就會產生冗餘的render,這時候就須要引入依賴,當這些參數發生變化的時候纔去執行我裏面的函數。
  • controlparams是 Effect 的依賴項,發生變化,useEffect()就會執行。
  • 若是想執行只運行一次的 effect(僅在組件掛載和卸載時執行),能夠傳遞一個空數組([])做爲第二個參數。
  • 將[inputRef]做爲useEffect的第二個參數傳遞,它實際上只在初始掛載時運行一次。

useContext

🔔第三步:讓函數組件跨組件共享狀態編輯器

const context = useContext(Context);
// Context 爲 context 對象(React.createContext 的返回值) // useContext 返回Context的返回值。 // 當前的 context 值由上層組件中距離當前組件最近的<Context.Provider> 的 value prop 決定。 複製代碼

useReducer

🔔第四步:讓函數組件緩存優化(應用更多場景 更深層)ide

const [state, dispatch] = useReducer(reducer, initialState);
 const initialState = {count: 0};  function reducer(state, action) {  switch (action.type) {  case 'increment':  return {count: state.count + 1};  case ‘decrement’:  return {count: state.count - 1};  default:  throw new Error();  } } function Counter() {  const [state, dispatch] = useReducer(reducer, initialState);  return (  <>  Count: {state.count}  <button onClick={() => dispatch({type: 'decrement'})}>-</button>  <button onClick={() => dispatch({type: 'increment'})}>+</button>  </>  ); } 複製代碼
  • useState 的替代方案,它接收一個形如 (state, action) => newState 的 reducer,並返回當前的 state 以及與其配套的 dispatch 方法

useCallback

🔔第四步:讓函數組件緩存優化(diff)函數

const memoizedCallback = useCallback(() => {fn(a, b);},[a, b],);
複製代碼

useMemo

🔔第四步:讓函數組件緩存優化(diff)性能

const memoizedValue = useMemo(() => fn(a, b), [a, b]);
複製代碼

useCallback:接收一個內聯回調函數參數和一個依賴項數組(子組件依賴父組件的狀態,即子組件會使用到父組件的值) ,useCallback 會返回該回調函數的 memoized 版本,該回調函數僅在某個依賴項改變時纔會更新 useMemo:把建立函數和依賴項數組做爲參數傳入 useMemo,它僅會在某個依賴項改變時才從新計算 memoized 值。這種優化有助於避免在每次渲染時都進行高開銷的計算flex

useRef

🔔第五步:讓函數組件能拿到一個可變,可是在組件的生命週期中指向的是同一個的ref對象優化

const refContainer = useRef(initialValue);
複製代碼

useImperativeHandle

useLayoutEffect

useDebugValue

(不太肯定有無問題,持續更新...)ui

本文使用 mdnice 排版

相關文章
相關標籤/搜索