最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

詳解React Hooks是如何工作的

 更新時(shí)間:2021年05月15日 09:14:50   作者:lovin  
React Hooks是在React 16.8版本新增的特性,在我看了React官網(wǎng)和一些博客對(duì)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ì)影響到外面的變量。

對(duì)于 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ù)或者是對(duì)象,由于我們在函數(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),并對(duì)該狀態(tài)進(jìn)行管理,以暴露出相關(guān)的操作接口的方式提供給函數(shù)組件使用。
這樣一來,函數(shù)組件就和其數(shù)據(jù)狀態(tài)分離了,函數(shù)組件只負(fù)責(zé)返回虛擬 DOM 本身就可以了,對(duì)于數(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ù)不對(duì),就會(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創(chuàng)建組件的的方式匯總

    React創(chuàng)建組件的的方式匯總

    React 是一個(gè)用于構(gòu)建用戶界面的 JAVASCRIPT 庫。這篇文章主要介紹了React組件的兩種創(chuàng)建方式,一種是使用函數(shù)創(chuàng)建組件另一種是使用類創(chuàng)建組件,需要的朋友可以參考下
    2021-11-11
  • 比ant更豐富Modal組件功能實(shí)現(xiàn)示例詳解

    比ant更豐富Modal組件功能實(shí)現(xiàn)示例詳解

    這篇文章主要為大家介紹了比ant更豐富Modal組件功能實(shí)現(xiàn)示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-11-11
  • 解決React報(bào)錯(cuò)Expected an assignment or function call and instead saw an expression

    解決React報(bào)錯(cuò)Expected an assignment or funct

    這篇文章主要為大家介紹了React報(bào)錯(cuò)Expected an assignment or function call and instead saw an expression解決方案詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-12-12
  • 解決React報(bào)錯(cuò)You provided a `checked` prop to a form field

    解決React報(bào)錯(cuò)You provided a `checked` prop&n

    這篇文章主要為大家介紹了React報(bào)錯(cuò)You provided a `checked` prop to a form field的解決方法詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-12-12
  • React如何將組件渲染到指定DOM節(jié)點(diǎn)詳解

    React如何將組件渲染到指定DOM節(jié)點(diǎn)詳解

    這篇文章主要給大家介紹了關(guān)于React如何將組件渲染到指定DOM節(jié)點(diǎn)的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)下吧。
    2017-09-09
  • React Hooks 實(shí)現(xiàn)和由來以及解決的問題詳解

    React Hooks 實(shí)現(xiàn)和由來以及解決的問題詳解

    這篇文章主要介紹了React Hooks 實(shí)現(xiàn)和由來以及解決的問題詳解,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-01-01
  • 淺談react性能優(yōu)化的方法

    淺談react性能優(yōu)化的方法

    這篇文章主要介紹了淺談react性能優(yōu)化的方法,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2018-09-09
  • Javascript之提高React性能的技巧

    Javascript之提高React性能的技巧

    一些剛開始學(xué)習(xí) React,或者從其他框架轉(zhuǎn)入 React 的開發(fā)者,一開始可能不會(huì)太關(guān)注性能。因?yàn)樾枰恍r(shí)間來發(fā)現(xiàn)新學(xué)習(xí)的框架的性能缺點(diǎn)。這篇文章主要介紹提高React性能的技巧,感興趣的同學(xué)可以參考閱讀
    2023-04-04
  • React里的Fragment標(biāo)簽的具體使用

    React里的Fragment標(biāo)簽的具體使用

    本文主要介紹了React里的Fragment標(biāo)簽的具體使用,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2023-01-01
  • react-navigation之動(dòng)態(tài)修改title的內(nèi)容

    react-navigation之動(dòng)態(tài)修改title的內(nèi)容

    這篇文章主要介紹了react-navigation之動(dòng)態(tài)修改title的內(nèi)容,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2018-09-09

最新評(píng)論

会泽县| 岳普湖县| 大连市| 长丰县| 大石桥市| 洛川县| 县级市| 华坪县| 克什克腾旗| 海原县| 安阳市| 波密县| 巴林右旗| 浦北县| 孟连| 象州县| 翁牛特旗| 石城县| 民乐县| 沂水县| 罗江县| 赞皇县| 东海县| 宝鸡市| 定结县| 阜新| 肥东县| 金门县| 什邡市| 阳春市| 盐亭县| 紫阳县| 宜兰市| 通辽市| 晋州市| 井陉县| 察隅县| 大邑县| 南漳县| 长岭县| 长宁区|