欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

詳解React Hooks是如何工作的

 更新時間:2021年05月15日 09:14:50   作者:lovin  
React Hooks是在React 16.8版本新增的特性,在我看了React官網和一些博客對React Hook的講解后還是覺得沒有get到本質。本篇博客通過手動實現(xiàn)useState()來了解Hook的原理和本質。閱讀此篇博客的前提是你要知道一些 React Hooks的基本用法和使用規(guī)則,不然會看得云里霧里。

1. React Hooks VS 純函數(shù)

React Hook 說白了就是 React V18.6 新增的一些 API,API的本質就是提供某種功能的函數(shù)接口。因此,React Hooks 就是一些函數(shù),但是 React Hooks 不是純函數(shù)。

什么是純函數(shù)呢?就是此函數(shù)在相同的輸入值時,需產生相同的輸出,并且此函數(shù)不能影響到外面的數(shù)據。
簡單理解就是函數(shù)里面不能用到在外面定義的變量,因為如果用到了外面定義的變量,當外面的變量改變時會影響函數(shù)內部的計算,函數(shù)也會影響到外面的變量。

對于 React Hooks 提供的函數(shù) API,恰恰就不是純函數(shù)。
來看一個 useState 的使用語句 const [count, setCount] = useState(0),使用 useState 函數(shù)得到的結果并不是全都一樣的,因為如果 useState(0) 每次得到的結果都是一樣的,那 count 值就永遠不會改變了,那 count 所在的頁面就永遠不會改變,和我們看到的結果就不一樣了。由此可知,React Hooks 都不是純函數(shù),也就是說 Hooks 用到了函數(shù)外的變量。

那么是什么特性讓 React Hooks 一定不能是純函數(shù)呢?實際上是 React 框架和函數(shù)組件本身決定的。我們知道,React 頁面渲染的原理就是通過每次 render 得到新的虛擬 DOM ,然后進行 DOM Diff 來渲染頁面。而 React 的函數(shù)組件是通過執(zhí)行整個函數(shù)得到一個虛擬 DOM。因此在每次頁面渲染 render 時,在函數(shù)組件內部的所有語句都會重新執(zhí)行一次。如果在函數(shù)組件內部使用的 React Hooks 是純函數(shù)的話,就不會在每次渲染后得到不同的虛擬 DOM 了。

React 規(guī)定: 所有 React 組件都必須是純函數(shù),并禁止修改其自身 props 。

因此在 React V16.8 之前 React Hooks 還沒出來的時候,函數(shù)組件因為是純函數(shù),只能返回一個固定的虛擬 DOM,不能包含狀態(tài),也不支持生命周期方法。因此,當時僅僅是支持函數(shù)組件,但函數(shù)組件相比于類組件限制太多,函數(shù)組件無法取代類組件,也沒類組件好用。

React 希望組件是簡單的而不是復雜的,React 認為組件的最佳寫法應該是函數(shù),而不是類。因此 React 就新增了 React Hooks,Hook 就是鉤子的意思,是 React 提供給函數(shù)組件在需要外部功能和數(shù)據狀態(tài)時將其 “鉤” 進去,從而完善函數(shù)組件,使其能完全代替類組件。

React 的函數(shù)組件只能是純函數(shù),那么每次事件發(fā)生時重新 render 函數(shù)組件時得到不同的虛擬 DOM 的事就完全交給了 React Hooks,那么 React Hooks 是如何做到的呢?下面就手動實現(xiàn)一個 useState,useState 的具體細節(jié)肯定不是這樣的,但原理和思路是一樣的。

2. 簡單 myUseState

React.useState 的第一次執(zhí)行是將初始值賦予給一個 _state,之后的每次重新 render 時就是讀取 _state 的值。[state, setState] 中的 setState 做的事就是改變 _state 的值,然后重新渲染頁面。
根據這個原理實現(xiàn) myUseState 函數(shù)如下:

import React from 'react';
import ReactDOM from 'react-dom';

let _state

function myUseState(initialValue){
  if(_state === undefined){
    _state = initialValue
  }
  const setState = (newValue)=>{
    _state = newValue
    render()
  }
  return [_state, setState]
}

function render(){
  ReactDOM.render(<App/>,document.getElementById('root'));
}

function App(){
  const [n, setN] = myUseState(0)
  return (
    <div>
      n: {n}
      <button onClick={() => setN(n+1)}>+1</button>
    </div>
  )
}

ReactDOM.render(<App/>,document.getElementById('root'));

3. 改進 myUseState

上述實現(xiàn)的 myUseState 存在 bug,當在函數(shù)組件內用到兩次 myUseState 時就會出現(xiàn)問題了,二者共用一個 _state 會出現(xiàn)混亂。
因此需要將上述實現(xiàn)進行改進,改進的思路就是將 _state 定義為一個數(shù)據或者是對象,由于我們在函數(shù)使用時只傳了一個數(shù)值,無法確定鍵值,因此只能使用數(shù)據。改進如下:

import React from 'react';
import ReactDOM from 'react-dom';

let _state = []
let index = 0

function myUseState(initialValue){
  const currentIndex = index
  if(_state[currentIndex] === undefined){
    _state[currentIndex] = initialValue
  }
  const setState = (newValue)=>{
    _state[currentIndex] = newValue
    render()
  }
  index++
  return [_state[currentIndex], setState]
}

function render(){
  index = 0
  ReactDOM.render(<App/>,document.getElementById('root'));
}

function App(){
  const [n, setN] = myUseState(0)
  const [m, setM] = myUseState(0)
  return (
    <div>
      n: {n}
      <button onClick={() => setN(n+1)}>+1</button>
      <br/>
      m: {m}
      <button onClick={() => setM(m+1)}>+1</button>
    </div>
  )
}

ReactDOM.render(<App/>,document.getElementById('root'));

4. 實現(xiàn)原理引發(fā)的 Hooks 規(guī)則

上述實現(xiàn)的 myUseState 肯定不是 React.useState 的具體實現(xiàn)代碼,但實現(xiàn)原理是一致的。myUseState 函數(shù)封裝了函數(shù)組件內的數(shù)據狀態(tài),并對該狀態(tài)進行管理,以暴露出相關的操作接口的方式提供給函數(shù)組件使用。
這樣一來,函數(shù)組件就和其數(shù)據狀態(tài)分離了,函數(shù)組件只負責返回虛擬 DOM 本身就可以了,對于數(shù)據狀態(tài)的管理完全交給其 “鉤” 住的 React.useState Hook 就可以了。

從上述的實現(xiàn)思路可以發(fā)現(xiàn),React Hooks 的實現(xiàn)其實是基于 全局變量 和 閉包 原理實現(xiàn)的特殊函數(shù)。

但是,正是因為這樣的實現(xiàn)方式,限制了 React Hooks 的使用必須是 只在頂層調用Hook,意思就是說 不要在循環(huán),條件或嵌套函數(shù)中調用 Hook,如果在 if 條件句中使用了 Hook, 導致組件每次渲染生成時 React.useState 語句的執(zhí)行次數(shù)不對,就會打亂 index 的計數(shù),從而導致數(shù)據維護的錯誤。

上述的實現(xiàn)原理依賴于 index 的正確計數(shù),因此 React 依賴于調用 Hooks 的順序,

以上就是詳解React Hooks是如何工作的的詳細內容,更多關于詳解React Hooks的資料請關注腳本之家其它相關文章!

相關文章

  • React useReducer終極使用教程

    React useReducer終極使用教程

    useReducer是在react V16.8推出的鉤子函數(shù),從用法層面來說是可以代替useState。相信前期使用過 React 的前端同學,大都會經歷從class語法向hooks用法的轉變,react的hooks編程給我們帶來了絲滑的函數(shù)式編程體驗
    2022-10-10
  • React?中使用?RxJS?優(yōu)化數(shù)據流的處理方案

    React?中使用?RxJS?優(yōu)化數(shù)據流的處理方案

    這篇文章主要為大家介紹了React?中使用?RxJS?優(yōu)化數(shù)據流的處理方案示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2023-02-02
  • 教你在react中創(chuàng)建自定義hooks

    教你在react中創(chuàng)建自定義hooks

    簡單來說就是使用自定義hook可以將某些組件邏輯提取到可重用的函數(shù)中。 自定義hook是一個從use開始的調用其他hook的Javascript函數(shù),下面看下react中創(chuàng)建自定義hooks的相關知識,感興趣的朋友一起看看吧
    2021-11-11
  • 從頭寫React-like框架的工程搭建實現(xiàn)

    從頭寫React-like框架的工程搭建實現(xiàn)

    這篇文章主要介紹了從頭寫React-like框架的工程搭建實現(xiàn),文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2021-04-04
  • React中Provider組件詳解(使用場景)

    React中Provider組件詳解(使用場景)

    這篇文章主要介紹了React中Provider組件使用場景,使用Provider可以解決數(shù)據層層傳遞和每個組件都要傳props的問題,本文結合示例代碼給大家介紹的非常詳細,感興趣的朋友跟隨小編一起看看吧
    2024-02-02
  • React文件名和目錄規(guī)范最佳實踐記錄(總結篇)

    React文件名和目錄規(guī)范最佳實踐記錄(總結篇)

    React在使用時非常靈活,如果沒有一個規(guī)范約束項目,在開發(fā)過程中會非?;靵y,本文將介紹幾個優(yōu)秀的規(guī)范,介紹文件名和目錄前,需要先簡述一下幾種通用的類型,用來區(qū)分文件的功能,感興趣的朋友一起看看吧
    2022-05-05
  • React的Props、生命周期詳解

    React的Props、生命周期詳解

    “Props” 是 React 中用于傳遞數(shù)據給組件的一種機制,通常作為組件的參數(shù)進行傳遞,在 React 中,props 是只讀的,意味著一旦將數(shù)據傳遞給組件的 props,組件就不能直接修改這些 props 的值,這篇文章主要介紹了React的Props、生命周期,需要的朋友可以參考下
    2024-06-06
  • React18新增特性released的使用

    React18新增特性released的使用

    本文主要介紹了React18新增特性released的使用,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2022-05-05
  • React手稿之 React-Saga的詳解

    React手稿之 React-Saga的詳解

    這篇文章主要介紹了React手稿之 React-Saga的詳解,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2018-11-11
  • 詳解React中常見的三種路由處理方式選擇

    詳解React中常見的三種路由處理方式選擇

    這篇文章主要為大家詳細介紹了React中常見的三種路由處理方式該如何選擇,文中的示例代碼講解詳細,感興趣的小伙伴可以跟隨小編一起學習一下
    2024-01-01

最新評論