亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

詳解React Hooks是如何工作的

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

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

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

什么是純函數(shù)呢?就是此函數(shù)在相同的輸入值時(shí),需產(chǎn)生相同的輸出,并且此函數(shù)不能影響到外面的數(shù)據(jù)。
簡單理解就是函數(shù)里面不能用到在外面定義的變量,因?yàn)槿绻玫搅送饷娑x的變量,當(dāng)外面的變量改變時(shí)會(huì)影響函數(shù)內(nèi)部的計(jì)算,函數(shù)也會(huì)影響到外面的變量。

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

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

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

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

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

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

2. 簡單 myUseState

React.useState 的第一次執(zhí)行是將初始值賦予給一個(gè) _state,之后的每次重新 render 時(shí)就是讀取 _state 的值。[state, setState] 中的 setState 做的事就是改變 _state 的值,然后重新渲染頁面。
根據(jù)這個(gè)原理實(shí)現(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. 改進(jìn) myUseState

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

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. 實(shí)現(xiàn)原理引發(fā)的 Hooks 規(guī)則

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

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

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

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

以上就是詳解React Hooks是如何工作的的詳細(xì)內(nèi)容,更多關(guān)于詳解React Hooks的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • React useReducer終極使用教程

    React useReducer終極使用教程

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

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

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

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

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

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

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

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

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

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

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

    React的Props、生命周期詳解

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

    React18新增特性released的使用

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

    React手稿之 React-Saga的詳解

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

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

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

最新評論