React中Hooks是什么

這篇文章給大家分享的是有關(guān)React中Hooks是什么的內(nèi)容。小編覺(jué)得挺實(shí)用的,因此分享給大家做個(gè)參考,一起跟隨小編過(guò)來(lái)看看吧。

創(chuàng)新互聯(lián)是一家專(zhuān)業(yè)提供甘谷企業(yè)網(wǎng)站建設(shè),專(zhuān)注與成都網(wǎng)站制作、網(wǎng)站設(shè)計(jì)、HTML5建站、小程序制作等業(yè)務(wù)。10年已為甘谷眾多企業(yè)、政府機(jī)構(gòu)等服務(wù)。創(chuàng)新互聯(lián)專(zhuān)業(yè)的建站公司優(yōu)惠進(jìn)行中。

什么是 Hooks

Hooks 譯為鉤子,Hooks 就是在函數(shù)組件內(nèi),負(fù)責(zé)鉤進(jìn)外部功能的函數(shù)。

React 提供了一些常用鉤子,React 也支持自定義鉤子,這些鉤子都是用于為函數(shù)引入外部功能。

當(dāng)我們?cè)诮M件中,需要引入外部功能時(shí),就可以使用 React 提供的鉤子,或者自定義鉤子。

比如在組件內(nèi)引入可管理 state 的功能,就可以使用 useState 函數(shù),下文會(huì)詳細(xì)介紹 useState 的用法。

為什么要用 Hooks

使用 Hooks 有 2 大原因:

  • 簡(jiǎn)化邏輯復(fù)用;

  • 讓復(fù)雜組件更易理解。

1. 簡(jiǎn)化邏輯復(fù)用

在 Hooks 出現(xiàn)之前,React 必須借用高階組件、render props 等復(fù)雜的設(shè)計(jì)模式才能實(shí)現(xiàn)邏輯的復(fù)用,但是高階組件會(huì)產(chǎn)生冗余的組件節(jié)點(diǎn),讓調(diào)試更加復(fù)雜。

Hooks 讓我們可以在無(wú)需修改組件結(jié)構(gòu)的情況下復(fù)用狀態(tài)邏輯,下文會(huì)詳細(xì)介紹自定義 Hooks 的用法。

2. 讓復(fù)雜組件更易理解

在 class 組件中,同一個(gè)業(yè)務(wù)邏輯的代碼分散在組件的不同生命周期函數(shù)中,而 Hooks 能夠讓針對(duì)同一個(gè)業(yè)務(wù)邏輯的代碼聚合在一塊,讓業(yè)務(wù)邏輯清晰地隔離開(kāi),讓代碼更加容易理解和維護(hù)。

四、常用的 Hooks

1. useState

useState 是允許你在 React 函數(shù)組件中添加 state 的 Hook。

使用示例如下:

import React, { useState } from 'react';

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

以上代碼聲明了一個(gè)初始值為 0 的 state 變量 count,通過(guò)調(diào)用 setCount 來(lái)更新當(dāng)前的 count。

2. useEffect

useEffect 可以讓你在函數(shù)組件中執(zhí)行副作用操作。

副作用是指一段和當(dāng)前執(zhí)行結(jié)果無(wú)關(guān)的代碼,常用的副作用操作如數(shù)據(jù)獲取、設(shè)置訂閱、手動(dòng)更改 React 組件中的 DOM。

useEffect 可以接收兩個(gè)參數(shù),代碼如下:

useEffect(callback, dependencies)

第一個(gè)參數(shù)是要執(zhí)行的函數(shù) callback,第二個(gè)參數(shù)是可選的依賴(lài)項(xiàng)數(shù)組 dependencies。

其中依賴(lài)項(xiàng)是可選的,如果不指定,那么 callback 就會(huì)在每次函數(shù)組件執(zhí)行完后都執(zhí)行;如果指定了,那么只有依賴(lài)項(xiàng)中的值發(fā)生變化的時(shí)候,它才會(huì)執(zhí)行。

使用示例如下:

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 () => {
        // 可用于做清除,相當(dāng)于 class 組件的 componentWillUnmount
    }

  }, [count]); // 指定依賴(lài)項(xiàng)為 count,在 count 更新時(shí)執(zhí)行該副作用
  // ...

以上代碼通過(guò) useEffect 實(shí)現(xiàn)了當(dāng)依賴(lài)項(xiàng) count 更新時(shí),執(zhí)行副作用函數(shù),并通過(guò)返回回調(diào)函數(shù)清除上一次的執(zhí)行結(jié)果。

另外,useEffect 提供了四種執(zhí)行副作用的時(shí)機(jī):

  • 每次 render 后執(zhí)行:不提供第二個(gè)依賴(lài)項(xiàng)參數(shù)。比如 useEffect(() => {});

  • 僅第一次 render 后執(zhí)行:提供一個(gè)空數(shù)組作為依賴(lài)項(xiàng)。比如 useEffect(() => {}, []);

  • 第一次以及依賴(lài)項(xiàng)發(fā)生變化后執(zhí)行:提供依賴(lài)項(xiàng)數(shù)組。比如 useEffect(() => {}, [deps]);

  • 組件 unmount 后執(zhí)行:返回一個(gè)回調(diào)函數(shù)。比如 useEffect() => { return () => {} }, [])。

3. useCallback

useCallback 定義的回調(diào)函數(shù)只會(huì)在依賴(lài)項(xiàng)改變時(shí)重新聲明這個(gè)回調(diào)函數(shù),這樣就保證了組件不會(huì)創(chuàng)建重復(fù)的回調(diào)函數(shù)。而接收這個(gè)回調(diào)函數(shù)作為屬性的組件,也不會(huì)頻繁地需要重新渲染。

使用示例如下:

const memoizedCallback = useCallback(() => {
  doSomething(a, b)
}, [a, b])

以上代碼在依賴(lài)項(xiàng) a、b 發(fā)生變化時(shí),才會(huì)重新聲明回調(diào)函數(shù)。

4. useMemo

useMemo 定義的創(chuàng)建函數(shù)只會(huì)在某個(gè)依賴(lài)項(xiàng)改變時(shí)才重新計(jì)算,有助于每次渲染時(shí)不會(huì)重復(fù)的高開(kāi)銷(xiāo)的計(jì)算,而接收這個(gè)計(jì)算值作為屬性的組件,也不會(huì)頻繁地需要重新渲染。

使用示例如下:

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

以上代碼在依賴(lài)項(xiàng) a、b 發(fā)生變化時(shí),才會(huì)重新計(jì)算。

5. useRef

useRef 返回一個(gè) ref 對(duì)象,這個(gè) ref 對(duì)象在組件的整個(gè)生命周期內(nèi)持續(xù)存在。

他有 2 個(gè)用處:

  • 保存 DOM 節(jié)點(diǎn)的引用

  • 在多次渲染之間共享數(shù)據(jù)。

保存 DOM 節(jié)點(diǎn)的引入使用示例如下:

function TextInputWithFocusButton() {
  const inputEl = useRef(null)
  const onButtonClick = () => {
    // `current` 指向已掛載到 DOM 上的文本輸入元素
    inputEl.current.focus()
  }
  return (
    <>
      <input ref={inputEl} type='text' />
      <button onClick={onButtonClick}>Focus the input</button>
    </>
  )
}

以上代碼通過(guò) useRef 創(chuàng)建了 ref 對(duì)象,保存了 DOM 節(jié)點(diǎn)的引用,可以對(duì) ref.current 做 DOM 操作。

在多次渲染之間共享數(shù)據(jù)示例如下:

import React, { useState, useCallback, useRef } from 'react'

export default function Timer() {
  // 定義 time state 用于保存計(jì)時(shí)的累積時(shí)間
  const [time, setTime] = useState(0)

  // 定義 timer 這樣一個(gè)容器用于在跨組件渲染之間保存一個(gè)變量
  const timer = useRef(null)

  // 開(kāi)始計(jì)時(shí)的事件處理函數(shù)
  const handleStart = useCallback(() => {
    // 使用 current 屬性設(shè)置 ref 的值
    timer.current = window.setInterval(() => {
      setTime((time) => time + 1)
    }, 100)
  }, [])

  // 暫停計(jì)時(shí)的事件處理函數(shù)
  const handlePause = useCallback(() => {
    // 使用 clearInterval 來(lái)停止計(jì)時(shí)
    window.clearInterval(timer.current)
    timer.current = null
  }, [])

  return (
    <div>
      {time / 10} seconds.
      <br />
      <button onClick={handleStart}>Start</button>
      <button onClick={handlePause}>Pause</button>
    </div>
  )
}

以上代碼通過(guò) useRef 創(chuàng)建了一個(gè)變量名為 timer 的 ref 對(duì)象,該對(duì)象可以在跨組件渲染時(shí)調(diào)用,在開(kāi)始計(jì)時(shí)時(shí)新建計(jì)時(shí)器,在暫停計(jì)時(shí)時(shí)清空計(jì)時(shí)器。

6. useContext

useContext 用于接收一個(gè) context 對(duì)象并返回該 context 的值,可以實(shí)現(xiàn)跨層級(jí)的數(shù)據(jù)共享。

示例如下:

// 創(chuàng)建一個(gè) context 對(duì)象
const MyContext = React.createContext(initialValue)
function App() {
  return (
    // 通過(guò) Context.Provider 傳遞 context 的值
    <MyContext.Provider value='1'>
      <Container />
    </MyContext.Provider>
  )
}

function Container() {
  return <Test />
}

function Test() {
  // 獲取 Context 的值
  const theme = useContext(MyContext) // 1
  return <div></div>
}

以上代碼通過(guò) useContext 取得了 App 組件中定義的 Context,做到了跨層次組件的數(shù)據(jù)共享。

7. useReducer

useReducer 用來(lái)引入 Reducer 功能。

示例如下:

const [state, dispatch] = useReducer(reducer, initialState)

它接受 Reducer 函數(shù)和狀態(tài)的初始值作為參數(shù),返回一個(gè)數(shù)組。數(shù)組的第一個(gè)成員是狀態(tài)的當(dāng)前值,第二個(gè)成員是發(fā)送 action 的 dispatch 函數(shù)。

五、自定義 Hooks

通過(guò)自定義 Hooks,可以將組件邏輯提取到可重用的函數(shù)中。

1. 如何創(chuàng)建自定義 Hooks?

自定義 Hooks 就是函數(shù),它有 2 個(gè)特征區(qū)分于普通函數(shù):

  • 名稱(chēng)以 “use” 開(kāi)頭;

  • 函數(shù)內(nèi)部調(diào)用其他的 Hook。

示例如下:

import { useState, useCallback } from 'react'

function useCounter() {
  // 定義 count 這個(gè) state 用于保存當(dāng)前數(shù)值
  const [count, setCount] = useState(0)
  // 實(shí)現(xiàn)加 1 的操作
  const increment = useCallback(() => setCount(count + 1), [count])
  // 實(shí)現(xiàn)減 1 的操作
  const decrement = useCallback(() => setCount(count - 1), [count])
  // 重置計(jì)數(shù)器
  const reset = useCallback(() => setCount(0), [])

  // 將業(yè)務(wù)邏輯的操作 export 出去供調(diào)用者使用
  return { count, increment, decrement, reset }
}

// 組件1
function MyComponent1() {
  const { count, increment, decrement, reset } = useCounter()
}

// 組件2
function MyComponent2() {
  const { count, increment, decrement, reset } = useCounter()
}

以上代碼通過(guò)自定義 Hooks useCounter,輕松的在 MyComponent1 組件和 MyComponent2 組件之間復(fù)用業(yè)務(wù)邏輯。

2. 自定義 Hooks 庫(kù) - react-use

React 官方提供了 react-use 庫(kù),其中封裝了大量可直接使用的自定義 Hooks,幫助我們簡(jiǎn)化組件內(nèi)部邏輯,提高代碼可讀性、可維護(hù)性。

其中我們常用的自定義 Hooks 有:

  • useLocation 和 useSearchParam:跟蹤頁(yè)面導(dǎo)航欄位置狀態(tài);

  • useScroll:跟蹤 HTML 元素的滾動(dòng)位置;

  • useScrolling:跟蹤 HTML 元素是否正在滾動(dòng);

  • useAsync, useAsyncFn, and useAsyncRetry:解析一個(gè) async 函數(shù);

  • useTitle:設(shè)置頁(yè)面的標(biāo)題。

感謝各位的閱讀!關(guān)于“React中Hooks是什么”這篇文章就分享到這里了,希望以上內(nèi)容可以對(duì)大家有一定的幫助,讓大家可以學(xué)到更多知識(shí),如果覺(jué)得文章不錯(cuò),可以把它分享出去讓更多的人看到吧!

文章名稱(chēng):React中Hooks是什么
當(dāng)前網(wǎng)址:http://www.muchs.cn/article42/pdhghc.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供網(wǎng)站營(yíng)銷(xiāo)、企業(yè)建站網(wǎng)站設(shè)計(jì)公司、搜索引擎優(yōu)化、網(wǎng)站內(nèi)鏈、品牌網(wǎng)站設(shè)計(jì)

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶(hù)投稿、用戶(hù)轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀(guān)點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話(huà):028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來(lái)源: 創(chuàng)新互聯(lián)

h5響應(yīng)式網(wǎng)站建設(shè)