成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

快速了解 React Hooks 原理

Hydrogen / 2205人閱讀

摘要:使用該對象,可以跟蹤屬于組件的各種元數(shù)據(jù)位。調(diào)用你的組件這意味著它知道存儲的元數(shù)據(jù)對象。下一次渲染會發(fā)生什么需要重新渲染組件由于之前已經(jīng)看過這個組件,它已經(jīng)有了元數(shù)據(jù)關(guān)聯(lián)。

為了保證的可讀性,本文采用意譯而非直譯。

想閱讀更多優(yōu)質(zhì)文章請猛戳GitHub博客,一年百來篇優(yōu)質(zhì)文章等著你!

我們大部分 React 類組件可以保存狀態(tài),而函數(shù)組件不能? 并且類組件具有生命周期,而函數(shù)組件卻不能?

React 早期版本,類組件可以通過繼承PureComponent來優(yōu)化一些不必要的渲染,相對于函數(shù)組件,React 官網(wǎng)沒有提供對應(yīng)的方法來緩存函數(shù)組件以減少一些不必要的渲染,直接 16.6 出來的 React.memo函數(shù)。

React 16.8 新出來的Hook可以讓React 函數(shù)組件具有狀態(tài),并提供類似 componentDidMountcomponentDidUpdate等生命周期方法。

類被會替代嗎?

Hooks不會替換類,它們只是一個你可以使用的新工具。React 團隊表示他們沒有計劃在React中棄用類,所以如果你想繼續(xù)使用它們,可以繼續(xù)用。

我能體會那種總有新東西要學(xué)的感覺有多痛苦,不會就感覺咱們總是落后一樣。Hooks 可以當(dāng)作一個很好的新特性來使用。當(dāng)然沒有必要用 Hook 來重構(gòu)原來的代碼, React團隊也建議不要這樣做。

Go Go

來看看Hooks的例子,咱們先從最熟悉的開始:函數(shù)組件。

以下 OneTimeButton 是函數(shù)組件,所做的事情就是當(dāng)我們點擊的時候調(diào)用 sayHi 方法。

import React from "react";
import { render } from "react-dom";

function OneTimeButton(props) {
  return (
    
  )
}

function sayHi() {
  console.log("yo")
}

render(
  ,
  document.querySelector("#root")
)

我們想讓這個組件做的是,跟蹤它是否被點擊,如果被點擊了,禁用按鈕,就像一次性開關(guān)一樣。

但它需要一個state,因為是一個函數(shù),它不可能有狀態(tài)(React 16.8之前),所以需要重構(gòu)成類。

函數(shù)組件轉(zhuǎn)換為類組件的過程中大概有5個階段:

*否認:也許它不需要是一個類,我們可以把 state 放到其它地方。

實現(xiàn): 廢話,必須把它變成一個class,不是嗎?

接受:好吧,我會改的。

努力加班重寫:首先 寫 class Thing extends React.Component,然后 實現(xiàn) render等等 。

最后:添加state。

class OneTimeButton extends React.Component {
  state = {
    clicked: false
  }

  handleClick = () => {
    this.props.onClick();

    // Ok, no more clicking.
    this.setState({ clicked: true });
  }

  render() {
    return (
      
    );
  }
}

這是相當(dāng)多的代碼,組件的結(jié)構(gòu)也發(fā)生了很大的變化, 我們需要多個小的功能,就需要改寫很多。

使用 Hook 輕松添加 State

接下來,使用新的 useState hook向普通函數(shù)組件添加狀態(tài):

import React, { useState } from "react"

function OneTimeButton(props) {
  const [clicked, setClicked] = useState(false)
  
  function doClick() {
    props.onClick();
    setClicked(true)
  }

  return (
    
  )
}
這段代碼是如何工作的

這段代碼的大部分看起來像我們一分鐘前寫的普通函數(shù)組件,除了useState。

useState是一個hook。 它的名字以“use”開頭(這是Hooks的規(guī)則之一 - 它們的名字必須以“use”開頭)。

useState hook 的參數(shù)是 state 的初始值,返回一個包含兩個元素的數(shù)組:當(dāng)前state和一個用于更改state 的函數(shù)。

類組件有一個大的state對象,一個函數(shù)this.setState一次改變整個state對象。

函數(shù)組件根本沒有狀態(tài),但useState hook允許我們在需要時添加很小的狀態(tài)塊。 因此,如果只需要一個布爾值,我們就可以創(chuàng)建一些狀態(tài)來保存它。

由于Hook以某種特殊方式創(chuàng)建這些狀態(tài),并且在函數(shù)組件內(nèi)也沒有像setState函數(shù)來更改狀態(tài),因此 Hook 需要一個函數(shù)來更新每個狀態(tài)。 所以 useState 返回是一對對應(yīng)關(guān)系:一個值,一個更新該值函數(shù)。 當(dāng)然,值可以是任何東西 - 任何JS類型 - 數(shù)字,布爾值,對象,數(shù)組等。

現(xiàn)在,你應(yīng)該有很多疑問,如:

當(dāng)組件重新渲染時,每次都不會重新創(chuàng)建新的狀態(tài)嗎? React如何知道舊狀態(tài)是什么?

為什么hook 名稱必須以“use”開頭? 這看起來很可疑。

如果這是一個命名規(guī)則,那是否意味著我可以自定義 Hook。

如何存儲更復(fù)雜的狀態(tài),很多場景不單單只有一個狀態(tài)值這么簡單。

Hooks 的魔力

將有狀態(tài)信息存儲在看似無狀態(tài)的函數(shù)組件中,這是一個奇怪的悖論。這是第一個關(guān)于鉤子的問題,咱們必須弄清楚它們是如何工作的。

原作者得的第一個猜測是某種編譯器的在背后操眾。搜索代碼useWhatever并以某種方式用有狀態(tài)邏輯替換它。

然后再聽說了調(diào)用順序規(guī)則(它們每次必須以相同的順序調(diào)用),這讓我更加困惑。這就是它的工作原理。

React第一次渲染函數(shù)組件時,它同時會創(chuàng)建一個對象與之共存,該對象是該組件實例的定制對象,而不是全局對象。只要組件存在于DOM中,這個組件的對象就會一直存在。

使用該對象,React可以跟蹤屬于組件的各種元數(shù)據(jù)位。

請記住,React組件甚至函數(shù)組件都從未進行過自渲染。它們不直接返回HTML。組件依賴于React在適當(dāng)?shù)臅r候調(diào)用它們,它們返回的對象結(jié)構(gòu)React可以轉(zhuǎn)換為DOM節(jié)點。

React有能力在調(diào)用每個組件之前做一些設(shè)置,這就是它設(shè)置這個狀態(tài)的時候。

其中做的一件事設(shè)置 Hooks 數(shù)組。 它開始是空的, 每次調(diào)用一個hook時,React 都會向該數(shù)組添加該 hook。

為什么順序很重要

假設(shè)咱們有以下這個組件:

function AudioPlayer() {
  const [volume, setVolume] = useState(80);
  const [position, setPosition] = useState(0);
  const [isPlaying, setPlaying] = useState(false);

  .....
}

因為它調(diào)用useState 3次,React 會在第一次渲染時將這三個 hook 放入 Hooks 數(shù)組中。

下次渲染時,同樣的3hooks以相同的順序被調(diào)用,所以React可以查看它的數(shù)組,并發(fā)現(xiàn)已經(jīng)在位置0有一個useState hook ,所以React不會創(chuàng)建一個新狀態(tài),而是返回現(xiàn)有狀態(tài)。

這就是React能夠在多個函數(shù)調(diào)用中創(chuàng)建和維護狀態(tài)的方式,即使變量本身每次都超出作用域。

多個useState 調(diào)用示例

讓咱們更詳細地看看這是如何實現(xiàn)的,第一次渲染:

React 創(chuàng)建組件時,它還沒有調(diào)用函數(shù)。React 創(chuàng)建元數(shù)據(jù)對象和Hooks的空數(shù)組。假設(shè)這個對象有一個名為nextHook的屬性,它被放到索引為0的位置上,運行的第一個hook將占用位置0。

React 調(diào)用你的組件(這意味著它知道存儲hooks的元數(shù)據(jù)對象)。

調(diào)用useState,React創(chuàng)建一個新的狀態(tài),將它放在hooks數(shù)組的第0位,并返回[volume,setVolume]對,并將volume 設(shè)置為其初始值80,它還將nextHook索引遞增1。

再次調(diào)用useState,React查看數(shù)組的第1位,看到它是空的,并創(chuàng)建一個新的狀態(tài)。 然后它將nextHook索引遞增為2,并返回[position,setPosition]。

第三次調(diào)用useState。 React看到位置2為空,同樣創(chuàng)建新狀態(tài),將nextHook遞增到3,并返回[isPlaying,setPlaying]。

現(xiàn)在,hooks 數(shù)組中有3個hook,渲染完成。 下一次渲染會發(fā)生什么?

React需要重新渲染組件, 由于 React 之前已經(jīng)看過這個組件,它已經(jīng)有了元數(shù)據(jù)關(guān)聯(lián)。

ReactnextHook索引重置為0,并調(diào)用組件。

調(diào)用useState,React查看索引0處的hooks數(shù)組,并發(fā)現(xiàn)它已經(jīng)在該槽中有一個hook。,所以無需重新創(chuàng)建一個,它將nextHook推進到索引1并返回[volume,setVolume],其中volume仍設(shè)置為80。

再次調(diào)用useState。 這次,nextHook1,所以React檢查數(shù)組的索引1。同樣,hook 已經(jīng)存在,所以它遞增nextHook并返回[position,setPosition]。

第三次調(diào)用useState,我想你知道現(xiàn)在發(fā)生了什么。

就是這樣了,知道了原理,看起來也就不那么神奇了, 但它確實依賴于一些規(guī)則,所以才有使用 Hooks 規(guī)則。

Hooks 的規(guī)則

自定義 hooks 函數(shù)只需要遵守規(guī)則 3 :它們的名稱必須以“use”為前綴。

例如,我們可以從AudioPlayer組件中將3個狀態(tài)提取到自己的自定義鉤子中:

function AudioPlayer() {
  // Extract these 3 pieces of state:
  const [volume, setVolume] = useState(80);
  const [position, setPosition] = useState(0);
  const [isPlaying, setPlaying] = useState(false);

  // < beautiful audio player goes here >
}

因此,咱們可以創(chuàng)建一個專門處理這些狀態(tài)的新函數(shù),并使用一些額外的方法返回一個對象,以便更容易啟動和停止播放,例如:

function usePlayerState(lengthOfClip) {
  const [volume, setVolume] = useState(80);
  const [position, setPosition] = useState(0);
  const [isPlaying, setPlaying] = useState(false);

  const stop = () => {
    setPlaying(false);
    setPosition(0);
  }

  const start = () => {
    setPlaying(true);
  }

  return {
    volume,
    position,
    isPlaying,
    setVolume,
    setPosition,
    start,
    stop
  };
}

像這樣提取狀態(tài)的一個好處是可以將相關(guān)的邏輯和行為組合在一起??梢蕴崛∫唤M狀態(tài)和相關(guān)事件處理程序以及其他更新邏輯,這不僅可以清理組件代碼,還可以使這些邏輯和行為可重用。

另外,通過在自定義hooks中調(diào)用自定義hooks,可以將hooks組合在一起。hooks只是函數(shù),當(dāng)然,函數(shù)可以調(diào)用其他函數(shù)。

總結(jié)

Hooks 提供了一種新的方式來處理React中的問題,其中的思想是很有意思且新奇的。

React團隊整合了一組很棒的文檔和一個常見問題解答,從是否需要重寫所有的類組件到鉤Hooks是否因為在渲染中創(chuàng)建函數(shù)而變慢? 以及兩者之間的所有東西,所以一定要看看。

代碼部署后可能存在的BUG沒法實時知道,事后為了解決這些BUG,花了大量的時間進行l(wèi)og 調(diào)試,這邊順便給大家推薦一個好用的BUG監(jiān)控工具 Fundebug。

交流

干貨系列文章匯總?cè)缦?,覺得不錯點個Star,歡迎 加群 互相學(xué)習(xí)。

https://github.com/qq44924588...

我是小智,公眾號「大遷世界」作者,對前端技術(shù)保持學(xué)習(xí)愛好者。我會經(jīng)常分享自己所學(xué)所看的干貨,在進階的路上,共勉!

關(guān)注公眾號,后臺回復(fù)福利,即可看到福利,你懂的。

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/109993.html

相關(guān)文章

  • 10分鐘了解 react 引入的 Hooks

    摘要:最近官方在大會上宣布內(nèi)測將引入。所以我們有必要了解,以及由此引發(fā)的疑問。在進一步了解之前,我們需要先快速的了解一些基本的的用法。如何解決狀態(tài)有關(guān)的邏輯的重用和共享問題。 showImg(https://segmentfault.com/img/remote/1460000016886798?w=1500&h=750); 大家好,我是谷阿莫,今天要將的是一個...,哈哈哈,看到這個題我就...

    Lucky_Boy 評論0 收藏0
  • React Hooks 從入門到上手

    摘要:前言樓主最近在整理的一些資料,為項目重構(gòu)作準(zhǔn)備,下午整理成了這篇文章。給傳入的是一個初始值,比如,這個按鈕的最初要顯示的是。取代了提供了一個統(tǒng)一的。 showImg(https://segmentfault.com/img/bVbpUle?w=900&h=550); Hooks are a new addition in React 16.8. They let you use sta...

    XFLY 評論0 收藏0
  • React Hooks 從入門到上手

    摘要:前言樓主最近在整理的一些資料,為項目重構(gòu)作準(zhǔn)備,下午整理成了這篇文章。給傳入的是一個初始值,比如,這個按鈕的最初要顯示的是。取代了提供了一個統(tǒng)一的。 showImg(https://segmentfault.com/img/bVbpUle?w=900&h=550); Hooks are a new addition in React 16.8. They let you use sta...

    zhouzhou 評論0 收藏0
  • 新上課程推薦:《React Hooks 案例詳解(React 進階必備)》

    摘要:課程制作和案例制作都經(jīng)過精心編排。對于開發(fā)者意義重大,希望對有需要的開發(fā)者有所幫助。是從提案轉(zhuǎn)為正式加入的新特性。并不需要用繼承,而是推薦用嵌套。大型項目中模塊化與功能解耦困難。從而更加易于復(fù)用和獨立測試。但使用會減少這種幾率。 showImg(https://segmentfault.com/img/bVbpNRZ?w=1920&h=1080); 講師簡介 曾任職中軟軍隊事業(yè)部,參與...

    Lin_YT 評論0 收藏0
  • 全面了解 React 新功能: Suspense 和 Hooks

    摘要:他們的應(yīng)用是比較復(fù)雜的,組件樹也是非常龐大,假設(shè)有一千個組件要渲染,每個耗費一千個就是由于是單線程的,這里都在努力的干活,一旦開始,中間就不會停。 悄悄的, React v16.7 發(fā)布了。 React v16.7: No, This Is Not The One With Hooks. showImg(https://segmentfault.com/img/bVblq9L?w=97...

    Baaaan 評論0 收藏0

發(fā)表評論

0條評論

最新活動
閱讀需要支付1元查看
<