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

react中hook介紹以及使用教程

 更新時間:2020年12月11日 09:34:14   作者:care_yourself  
這篇文章主要給大家介紹了關(guān)于react中hook及使用的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧

前言

最近由于公司的項目開發(fā),就學(xué)習(xí)了在react關(guān)于hook的使用,對其有個基本的認(rèn)識以及如何在項目中去應(yīng)用hook。在這篇博客中主要從以下的幾個點進(jìn)行介紹:

  • hook簡介
  • hook中常用api的使用
  • hook在使用過程中需要去注意的地方
  • hook中怎樣去實現(xiàn)class組件中的聲明周期函數(shù)

hook

首先介紹關(guān)于hook的含義,以及其所要去面對的一些場景

含義:Hook 是 React 16.8 的新增特性。它可以讓你在不編寫 class 的情況下使用 state 以及其他的 React 特性。簡單來說就是可以使用函數(shù)組件去使用react中的一些特性

所要解決的問題:

  • 解決組件之間復(fù)用狀態(tài)邏輯很難得問題,hook能解決的就是在你無需修改之前組件結(jié)構(gòu)的情況下復(fù)用狀態(tài)邏輯,在不使用hook的情況下,需要使用到一些高級的用法如高級組件、provider、customer等,這種方式對于新手來說不太友好,可能在理解上就比較的困難
  • 對于復(fù)雜組件可以去拆分其邏輯,例如在你使用生命周期函數(shù)時,不同的生命周期需要在不同的時刻進(jìn)行,因此在此時對于復(fù)雜的組件來說,有的生命周期函數(shù)中就存在大量的邏輯,在可讀性上面就大打折扣。當(dāng)使用hook時,就可以進(jìn)行組件邏輯的劃分,將相同的邏輯給整合在一起,這樣就大大增加可讀性也在一方面利于維護(hù)
  • 不需要對于class組件的理解,當(dāng)你在最初去學(xué)習(xí)時,你不得不去理解this這個關(guān)鍵字,在當(dāng)前組件所表示的含義,但是在hook中就不需要。能夠解決你在不使用class組件的情況下去體現(xiàn)react的特性
  • 需要注意的一點就是hook和class組件是不能夠同時使用的,在實際的使用過程中一定要注意,否則就會出現(xiàn)報錯

那么接下來所要介紹的部分就是如何去使用hook

state hook

對于使用過class組件的同學(xué),相信對于state肯定有很深的印象,對于一些需要用到的全局變量,在class組件中我們常常采用的方式是this.state = {},但是在hook中我們采用的方式就是使用useState這個hook,然后就可以對這種全局變量進(jìn)行引用,在引用時只需要用其變量名即可,這里就拿官網(wǎng)的例子來舉例:
import React, { useState } from 'react';

import React, { useState } from 'react';

function Example() {
 // 聲明一個叫 "count" 的 state 變量
 const [count, setCount] = useState(0);

 return (
 <div>
  <p>You clicked {count} times</p>
  <button onClick={() => setCount(count + 1)}>
  Click me
  </button>
 </div>
 );
}

在上面的這個例子中,我們設(shè)置變量方式采用的就是const [count, setCount] = useState(0)這種方式,其中的0就是給count賦初值為0,如果想要給count賦值為一個空對象,那么只需要const [count, setCount] = useState({}),這樣的方式就行了,那么這樣你在用count時,此時獲取到的值就為一個空對象。

作用:返回一個state,以及更新state的函數(shù)

  1. 函數(shù)式更新:新的state需要通過使用先前的state計算得出,將函數(shù)傳遞給setState,該函數(shù)將接收先前的state,并返回一個更新后的值
  2. 惰性初始state,initialState參數(shù)只會在組件的初始渲染中起作用,如果初始化state需要通過一個復(fù)雜計算來獲取,則可以傳入一個函數(shù),在函數(shù)中計算并返回初始的state,此函數(shù)只在初始渲染時被掉用,如下所示:
 const [state, setState] = useState(() => {
  const initialState = someExpensiveComputation(props);
  return initialState;
 })

在hook中如何給全局變量設(shè)置值

在class組件中我們給放在state中的變量賦值時,通常采用的方式就是this.setState()這種方式,那么在hook中所要采用的就是set+變量名這種方式,如

const [count, setCount] = useState(0)

在這里通過上面我們已經(jīng)知道的就是count能夠獲取到值,那么其所對應(yīng)的setCount(值),這種賦值的方式就是給count變量賦值的,然后通過count就能夠獲取到值。

  • 為什么要采用這種方式呢?
  • 原因:是因為react中的單向數(shù)據(jù)源,這樣的話,能夠保證你的數(shù)據(jù)源流向會更加的清楚,這也是react所區(qū)別于vue中雙向數(shù)據(jù)源綁定的一點

hook中設(shè)置多個全局變量的方式

在hook中,如果我們需要去設(shè)置多個類似于上面所說的count,那么就需要多次使用useState這個hook,當(dāng)然你也可以設(shè)置一個變量在hook的最外部,即在hook這個函數(shù)組件的外部。需要注意的是別在整個hook這個函數(shù)的全局設(shè)置,因此在hook的運行機制中,在每次加載時,都會從新去加載里面的變量,因此你是不能夠去獲取到在整個函數(shù)內(nèi)部中使用該變量所改變的值的,能夠獲取到的就只是這個變量的初始值*

useEffect hook

對于useEffect hook,其用途類似于class組件中的生命周期函數(shù),用來處理在一些特定時刻需要去做的事情,這種事情常被叫做副作用。在使用useEffect這個hook時,需要注意的一點就是其不能夠被包含在循環(huán),判斷語句中,否則項目會出現(xiàn)報錯,這也是hook的一種設(shè)置機制

  • 副作用的劃分:
    • 不需要清除的: 在React更新DOM之后運行一些額外的代碼:如:發(fā)送網(wǎng)絡(luò)請求,手動變更DOM,記錄日志等
    • 需要清除的:當(dāng)使用外部數(shù)據(jù)源時,需要去清除數(shù)據(jù),如:定時器,需要我們在結(jié)束的時候去清除
  • 渲染時機:在使用useEffect這個hook時,需要注意的就是其渲染的時機,默認(rèn)情況下會在第一次渲染和每一次更新時去執(zhí)行。對于如何去控制這個渲染時機,在下面的一個部分會有詳細(xì)的介紹
  • 作用:告訴組件在渲染之后執(zhí)行某些操作
  • useEffect放在組件內(nèi)部調(diào)用的原因:可以在effect中直接訪問state中的變量
  • effect返回函數(shù):effect可選的清除機制,每個effect都可以返回一個清除函數(shù)
  • 接收內(nèi)容:一個包含命令式、并且可能有副作用代碼的函數(shù)
  • 清除effect:實現(xiàn)方式,effect函數(shù)需要返回一個清除函數(shù)
  • effect執(zhí)行時機:在瀏覽器完成布局和繪制之后,傳給useEffect的函數(shù)會延遲調(diào)用,因此不應(yīng)該在函數(shù)中執(zhí)行足賽瀏覽器更新屏幕的操作。
  • 默認(rèn)條件執(zhí)行:會在每輪組件渲染完成后執(zhí)行,因而一旦effect的依賴發(fā)生變化,他就會被重新創(chuàng)建。要改變其執(zhí)行時機,需要給useEffect傳遞第二個參數(shù),只有當(dāng)?shù)诙€參數(shù)值發(fā)生改變才會重新創(chuàng)建訂閱。如果要使用這個優(yōu)化的方式,需要確保數(shù)組包含了所有外部作用域中會發(fā)發(fā)生變化,且在effect中使用的變量。如果只想運行一次effect,可以傳遞一個空數(shù)組作為第二個參數(shù)。

對于useEffect的初步認(rèn)識只需要了解上面的即可。接下來就來介紹一個官網(wǎng)的實例,來說明useEffect

import React, { useState, useEffect } from 'react';

function Example() {
 const [count, setCount] = useState(0);

 // Similar to componentDidMount and componentDidUpdate:
 useEffect(() => {
  // Update the document title using the browser API
  document.title = `You clicked ${count} times`;
 });

 return (
  <div>
   <p>You clicked {count} times</p>
   <button onClick={() => setCount(count + 1)}>
    Click me
   </button>
  </div>
 );
}

在上面的這段代碼中,就使用到了useEffect這個hook,在每次count值改變時,就會在頁面中去打印“You clicked ${count} times”這段文字,當(dāng)然count肯定對應(yīng)的就是其所對應(yīng)的值。

useEffect去取代calss中的生命周期函數(shù)的方式

react中有狀態(tài)組件中,其生命周期函數(shù)的各個階段

  1. 在Mounting階段
    1. constructor()
    2. static getDerivedStateFromProps()
    3. render()
    4. componentDidMount()
  2. Updating
    1. static getDerivedStateFormProps
    2. shouldComponentUpdate()
    3. render()
    4. getSnapshotBeforeUpdate()
    5. componentDidUpdate()
  3. UnMouting
    1. componentWillUnmount()

使用hook去代替生命周期函數(shù)的方式

這里就介紹了關(guān)于useEffect這個hook的使用,有一些生命周期函數(shù)就是通過該hook來實現(xiàn)的,這里推薦一篇文章https://blog.logrocket.com/guide-to-react-useeffect-hook/,可以參考下。這里是在參考了一些文章后寫的,具體介紹如下:

constructor: 可以通過useState來初始化state

componentDidMount(),在hook中需要使用下面的這種方式去取代,在useEffect中傳遞第二個參數(shù),該參數(shù)為一個空數(shù)組,只會去執(zhí)行一次,如下面所示

useEffect(() => {

},[])

componentDidUpdate(),有兩種方式去解決

在每次渲染的時候都去調(diào)用hooks,解決的方式如下面所示

  useEffect(() => {

  })

用一個特殊變量的去觸發(fā)hook,如下面所示,count指的就是這個特殊的變量,該hook觸發(fā),只會是count的值改變時

  useEffect(() => {

  },[count])

componentWillUnmount(),用hook來代替,需要去return一個callback(回調(diào)函數(shù)),如下面的形式所示

  useEffect(() => {
    return () => {
      //執(zhí)行的為componentWillUnmount
    }
  },[])

shouldComponentUpdata(),常使用React.memo來代替,在默認(rèn)情況下,它將對props對象中的復(fù)雜對象進(jìn)行淺層比較,如果想要去控制比較,可以去提供一個自定義的比較函數(shù)作為第二個參數(shù)。代替hook的方式如下所示

  import React from 'react'
  function areEqual(prevProps, nextProps) {
  /*
  return true if passing nextProps to render would return
  the same result as passing prevProps to render,
  otherwise return false
  */
  }
  const Weather = ({weather}) => {
    return (<div>
        <p>{weather.city}</p>
        <p>{weather.temperature}</p>
        {console.log('Render')}
        </div>
    )
  }

  export default React.memo(Weather, areEqual)

自定義hook

通常在實際的項目開發(fā)中少不了使這種自定義的hook,前提是在整個項目中使用了hook的情況下。通常情況下就是去使用useState,useEffect這種系統(tǒng)已經(jīng)定義好的hook去實現(xiàn),在調(diào)用時你就可以直接調(diào)用當(dāng)你自定義好的hook來實現(xiàn)你所需要的功能。下面就以自定義useReducer這個hook為例

import React, { useEffect } from 'react'

function useReducer(reducer, initialState) {
 const [state, setState] = useState(initialState);

 function dispatch(action) {
  const nextState = reducer(state, action);
  setState(nextState);
 }

 return [state, dispatch];
}
export default useReducer

在上面的這個實際例子中,我們封裝了一個自定義的useReducerhook,我們可以調(diào)用這個hook去完成與reducer一樣的功能了,在調(diào)用是就需要我們?nèi)魅雰蓚€參數(shù),一個就是reducer,另外一個就是initialState,然后就能夠取得state,以及dispatch方法。注意這里的返回值使用的是一個數(shù)組,這樣的好處就是我們在獲取其返回值時,可以采用數(shù)組結(jié)構(gòu)這種方式來獲取。具體關(guān)于數(shù)組的結(jié)構(gòu)可以去看看es6中的部分,就能夠明白了。那么接下來就是使用這個自定義好的useReducer。使用方式如下

import useReducer form '你封裝useRecuer的組件中'
function Todos() {
const todosReducer = ( state, dispatch) => {
	if(dispatch.type == "") { //type值為什么時去執(zhí)行
		const newState == "" //執(zhí)行一些操作,去更新state
		return newState //返回新的neState
	}
}
 const [todos, dispatch] = useReducer(todosReducer, []);
 function handleAddClick(text) {
  dispatch({ type: 'add', text });
 }

 return (
	<div></div>
)
}

這里并沒有把實際的使用情況給寫完,剩余的可以自己去補充,其使用方式就和redux的使用方式相同。這就是整個自定義hook以及去使用的過程,在實際的開發(fā)中可以去體驗體驗。

額外的hook

useReducer,能給那些會出發(fā)深更新的組件做性能優(yōu)化,因為可以向子組件去傳遞dispatch而不是回調(diào)

useReducer這個hook的封裝,整個封裝的方法如下:

//reducer hook封裝
  import { useState } from 'react';
  export default useReducer function(reducer, initialState) {
    const [state, setState] = useState(initialState);
    function dispatch(action){
      const nextState = reducer(state, action);
      return setState(nextState);
    }
    return [state, dispatch]
  }
//實際例子使用
  import useReducer from '';
  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();
  }
  }
  return (
    <div>
      Count: {state.count}
      <button onClick={() => dispatch({type: 'devrement'})}>-</button>
      <button onClick={() => dispatch({type: 'increment'})}>+</button>
    </div>
  )

useReducer的惰性初始化,可以選擇惰性地創(chuàng)建初始化state。因此需要設(shè)置一個初始化函數(shù)作為useReducer的第三個參數(shù)傳入,這樣初始化state將設(shè)置為init(initialArg),如下所示,就是一個實際的案例在useReducer中去傳遞第三個參數(shù)

function init(initialCount) {
 return {count: initialCount};
}

function reducer(state, action) {
 switch (action.type) {
  case 'increment':
   return {count: state.count + 1};
  case 'decrement':
   return {count: state.count - 1};
  case 'reset':
   return init(action.payload);
  default:
   throw new Error();
 }
}

function Counter({initialCount}) {
 const [state, dispatch] = useReducer(reducer, initialCount, init);
 return (
  <>
   Count: {state.count}
   <button
    onClick={() => dispatch({type: 'reset', payload: initialCount})}>
    Reset
   </button>
   <button onClick={() => dispatch({type: 'decrement'})}>-</button>
   <button onClick={() => dispatch({type: 'increment'})}>+</button>
  </>
 );
}

注意:如果reducer hook的返回值與當(dāng)前state相同,react將跳過子組件的渲染及副作用的執(zhí)行

useCallback

返回值:返回一個memoized回調(diào)函數(shù),該回調(diào)函數(shù)僅在某給依賴項改變時才會更新。

含義:把內(nèi)聯(lián)回調(diào)函數(shù)及其依賴項數(shù)組作為參數(shù)傳入useCallback,它將返回該回調(diào)函數(shù)傳遞給經(jīng)過優(yōu)化的并使用引用相等性去避免非必要渲染

useCallBack(fn, deps)相當(dāng)與useMemo(() => fn,deps)

useMemo

使用方式:const memoziedValue = useMemo(() => computeExpensiveValue(a,b), [a, b])

返回值:返回一個memoized值,把創(chuàng)建函數(shù)和依賴項數(shù)組作為參數(shù)傳入useMemo,僅在某個依賴項改變時才重新計算memoized值。

好處:這種優(yōu)化有助于避免在每次渲染時都進(jìn)行高開銷的計算

渲染方式:傳入useMemo的函數(shù)會在渲染期間執(zhí)行,不要在這個函數(shù)內(nèi)部執(zhí)行與渲染無關(guān)的操作,如屬于useEffect中的副作用。如果沒有,那么新的值將會在每次渲染時被重新渲染

注意:依賴項數(shù)組不會作為參數(shù)傳遞給函數(shù),概述來說,就是每一個出現(xiàn)在函數(shù)中的參數(shù)也應(yīng)該出現(xiàn)在依賴項的數(shù)組中

useRef

使用方式: const refContainer = useref(initialValue);

返回值:返回一個可ref對象,其.current屬性被初始化為傳入的參數(shù)(initialValue)。這返回的的對象將在組件的整個生命周期中持續(xù)

含義: useRef就像是一個盒子可以將.current中得可變屬性給保存起來

ref與useRef的區(qū)別在于,后者是創(chuàng)建的了一個普通的js對象,useRef和自建一個{current: …。}對象的唯一區(qū)別是,useRef會在每次渲染時,返回同一個ref對象

useImperativeHandle

作用:可以在使用ref時自定義暴露給賦組件的實例值,使用的形式如下:

useImperativeHandle(ref, createHandle, [deps])

useLayoutEffect

更新時機:在瀏覽器執(zhí)行下一次繪制前去執(zhí)行

與useEffect相同,會在所有的DOM變更之后同步調(diào)用effect

useDebugValue

作用:在react devTools中常被用于去當(dāng)作展示標(biāo)簽,作為客戶端的鉤子

hooks中的性能優(yōu)化

在hook中,其性能優(yōu)化的點很多,這個可以在一些https://react.docschina.org/docs/hooks-faq.html#performance-optimizations去學(xué)習(xí),下面是我看的一部分。

如何在更新時去跳過effect,可以采用條件式方式,即在useEffect中去傳遞第二個參數(shù)

由于某些原因,無法將一個函數(shù)移動到effect內(nèi)部時,可采用下面方式

  1. 嘗試將函數(shù)移動到當(dāng)前組件的外部
  2. 如果所調(diào)用對策方法是一個純計算等,此時可以在effect外面去寫這個函數(shù)
  3. 如果要增加一個函數(shù)去依賴項,那么要明確使用useCallback外部的hook,如下面的例子所示
function ProductPage({ productId }) {
// Wrap with useCallback to avoid change on every render
const fetchProduct = useCallback(() => {
  // ... Does something with productId ...
}, [productId]); // All useCallback dependencies are specified

return <ProductDetails fetchProduct={fetchProduct} />;
}

function ProductDetails({ fetchProduct }) {
useEffect(() => {
  fetchProduct();
}, [fetchProduct]); // All useEffect dependencies are specified
// ...
}

實現(xiàn)shouldComponentUpdate的方式

  const Button = React.memo((props) => {
  // your component
  });

如上面所示,這種實現(xiàn)方式并不是使用了hooks,它相當(dāng)于純組件,但是僅僅能夠比較的是props。可以去增加第二個參數(shù),采用一種函數(shù)的方式去拿到新老的props,如果結(jié)果返回true,就跳過更新階段

記住計算結(jié)果的方式

使用useMemo這個hook去記住之前的計算結(jié)果,從而在多個渲染之中緩存計算

const memoizedValue = useMemo(() => computeExpensiveValue(a, b), [a, b]);

上面的代碼會調(diào)用computeExpensiveValue(a,b)這個函數(shù),但是它們依賴的a,b沒有改變,那么useMemo在直接去返回上一次結(jié)果的值

結(jié)語

對于hook的學(xué)習(xí)大概就如上面所說,對于hook其中的內(nèi)容還很多所以對于hook的學(xué)習(xí)最好是去官網(wǎng)看看,鏈接如下https://react.docschina.org/docs/hooks-intro.html在官網(wǎng)中介紹的更加詳細(xì),這里的中文文檔和英文文檔內(nèi)容都一樣,不過對于英文好的同學(xué)建議看看英文版本。

到此這篇關(guān)于react中hook的介紹以及使用的文章就介紹到這了,更多相關(guān)react中hook介紹及使用內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • React服務(wù)端渲染原理解析與實踐

    React服務(wù)端渲染原理解析與實踐

    這篇文章主要介紹了React服務(wù)端渲染原理解析與實踐,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2021-03-03
  • React中props使用教程

    React中props使用教程

    props是組件(包括函數(shù)組件和class組件)間的內(nèi)置屬性,用其可以傳遞數(shù)據(jù)給子節(jié)點,props用來傳遞參數(shù)。組件實例化過程中,你可以向其中傳遞一個參數(shù),這個參數(shù)會在實例化過程中被引用
    2022-09-09
  • react?native?reanimated實現(xiàn)動畫示例詳解

    react?native?reanimated實現(xiàn)動畫示例詳解

    這篇文章主要為大家介紹了react?native?reanimated實現(xiàn)動畫示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-03-03
  • 解決React Native端口號修改的方法

    解決React Native端口號修改的方法

    這篇文章主要介紹了解決React Native端口號修改的方法,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-07-07
  • 關(guān)于react hook useState連續(xù)更新對象的問題

    關(guān)于react hook useState連續(xù)更新對象的問題

    這篇文章主要介紹了關(guān)于react hook useState連續(xù)更新對象的問題,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2024-03-03
  • react ant protable自定義實現(xiàn)搜索下拉框

    react ant protable自定義實現(xiàn)搜索下拉框

    這篇文章主要介紹了react ant protable自定義實現(xiàn)搜索下拉框,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2023-06-06
  • React 高階組件入門介紹

    React 高階組件入門介紹

    本篇文章主要介紹了React高階組件入門介紹,這篇文章中我們詳細(xì)的介紹了什么是高階組件,如何使用高階組件,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2018-01-01
  • react實現(xiàn)換膚功能的示例代碼

    react實現(xiàn)換膚功能的示例代碼

    這篇文章主要介紹了react實現(xiàn)換膚功能的示例代碼,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2018-08-08
  • 一文掌握React?組件樹遍歷技巧

    一文掌握React?組件樹遍歷技巧

    這篇文章主要為大家介紹了React?組件樹遍歷技巧的掌握,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-04-04
  • React Fiber結(jié)構(gòu)的創(chuàng)建步驟

    React Fiber結(jié)構(gòu)的創(chuàng)建步驟

    這篇文章主要介紹了React Fiber結(jié)構(gòu)的創(chuàng)建步驟,幫助大家更好的理解和學(xué)習(xí)使用React,感興趣的朋友可以了解下
    2021-04-04

最新評論