溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

React的Hook是什么

發(fā)布時間:2022-03-16 13:34:04 來源:億速云 閱讀:166 作者:小新 欄目:開發(fā)技術(shù)

這篇文章主要介紹了React的Hook是什么,具有一定借鑒價值,感興趣的朋友可以參考下,希望大家閱讀完這篇文章之后大有收獲,下面讓小編帶著大家一起了解一下。


      State Hook

      這個例子用來顯示一個計數(shù)器。當(dāng)你點擊按鈕,計數(shù)器的值就會增加:

      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>
        );
      }

      在這里,useState 就是一個 Hook (等下我們會講到這是什么意思)。通過在函數(shù)組件里調(diào)用它來給組件添加一些內(nèi)部 state。React 會在重復(fù)渲染時保留這個 state。useState 會返回一對值:當(dāng)前狀態(tài)一個讓你更新它的函數(shù),你可以在事件處理函數(shù)中或其他一些地方調(diào)用這個函數(shù)。它類似 class 組件的 this.setState,但是它不會把新的 state 和舊的 state 進(jìn)行合并。(我們會在使用 State Hook 里展示一個對比 useState 和 this.state 的例子)。

      useState 唯一的參數(shù)就是初始 state。在上面的例子中,我們的計數(shù)器是從零開始的,所以初始 state 就是 0。值得注意的是,不同于 this.state,這里的 state 不一定要是一個對象 &mdash;&mdash; 如果你有需要,它也可以是。這個初始 state 參數(shù)只有在第一次渲染時會被用到。

      聲明多個 state 變量

      你可以在一個組件中多次使用 State Hook:

      function ExampleWithManyStates() {
        // 聲明多個 state 變量!
        const [age, setAge] = useState(42);
        const [fruit, setFruit] = useState('banana');
        const [todos, setTodos] = useState([{ text: 'Learn Hooks' }]);
        // ...
      }

      數(shù)組解構(gòu)的語法讓我們在調(diào)用 useState 時可以給 state 變量取不同的名字。當(dāng)然,這些名字并不是 useState API 的一部分。React 假設(shè)當(dāng)你多次調(diào)用 useState 的時候,你能保證每次渲染時它們的調(diào)用順序是不變的。后面我們會再次解釋它是如何工作的以及在什么場景下使用。

      那么,什么是 Hook?

      Hook 是一些可以讓你在函數(shù)組件里 " 鉤入" React state 及生命周期等特性的函數(shù)。Hook 不能在 class 組件中使用 &mdash;&mdash; 這使得你不使用 class 也能使用 React。(我們不推薦把你已有的組件全部重寫,但是你可以在新組件里開始使用 Hook。)

      React 內(nèi)置了一些像 useState 這樣的 Hook。你也可以創(chuàng)建你自己的 Hook 來復(fù)用不同組件之間的狀態(tài)邏輯。我們會先介紹這些內(nèi)置的 Hook。

      Effect Hook

      你之前可能已經(jīng)在 React 組件中執(zhí)行過數(shù)據(jù)獲取、訂閱或者手動修改過 DOM。我們統(tǒng)一把這些操作稱為“副作用”,或者簡稱為“作用”。

      useEffect 就是一個 Effect Hook,給函數(shù)組件增加了操作副作用的能力。它跟 class 組件中的 componentDidMount、componentDidUpdate 和 componentWillUnmount 具有相同的用途,只不過被合并成了一個 API。

      例如,下面這個組件在 React 更新 DOM 后會設(shè)置一個頁面標(biāo)題:

      import React, { useState, useEffect } from 'react';
      function Example() {
        const [count, setCount] = useState(0);
        // 相當(dāng)于 componentDidMount 和 componentDidUpdate:
        useEffect(() => {
          // 使用瀏覽器的 API 更新頁面標(biāo)題
          document.title = `You clicked ${count} times`;
        });
        return (
          <div>
            <p>You clicked {count} times</p>
            <button onClick={() => setCount(count + 1)}>
              Click me
            </button>
          </div>
        );
      }

      當(dāng)你調(diào)用 useEffect 時,就是在告訴 React 在完成對 DOM 的更改后運(yùn)行你的“副作用”函數(shù)。由于副作用函數(shù)是在組件內(nèi)聲明的,所以它們可以訪問到組件的 props 和 state。默認(rèn)情況下,React 會在每次渲染后調(diào)用副作用函數(shù) &mdash;&mdash; 包括第一次渲染的時候。

      副作用函數(shù)還可以通過返回一個函數(shù)來指定如何“清除”副作用。例如,在下面的組件中使用副作用函數(shù)來訂閱好友的在線狀態(tài),并通過取消訂閱來進(jìn)行清除操作:

      import React, { useState, useEffect } from 'react';
      function FriendStatus(props) {
        const [isOnline, setIsOnline] = useState(null);
        function handleStatusChange(status) {
          setIsOnline(status.isOnline);
        }
        useEffect(() => {
          ChatAPI.subscribeToFriendStatus(props.friend.id, handleStatusChange);
          return () => {
            ChatAPI.unsubscribeFromFriendStatus(props.friend.id, handleStatusChange);
          };
        });
        if (isOnline === null) {
          return 'Loading...';
        }
        return isOnline ? 'Online' : 'Offline';
      }

      在這個示例中,React 會在組件銷毀時取消對 ChatAPI 的訂閱,然后在后續(xù)渲染時重新執(zhí)行副作用函數(shù)。(如果傳給 ChatAPI 的 props.friend.id 沒有變化,你也可以告訴 React 跳過重新訂閱。)

      跟 useState 一樣,你可以在組件中多次使用 useEffect :

      function FriendStatusWithCounter(props) {
        const [count, setCount] = useState(0);
        useEffect(() => {
          document.title = `You clicked ${count} times`;
        });
        const [isOnline, setIsOnline] = useState(null);
        useEffect(() => {
          ChatAPI.subscribeToFriendStatus(props.friend.id, handleStatusChange);
          return () => {
            ChatAPI.unsubscribeFromFriendStatus(props.friend.id, handleStatusChange);
          };
        });
        function handleStatusChange(status) {
          setIsOnline(status.isOnline);
        }
        // ...

      通過使用 Hook,你可以把組件內(nèi)相關(guān)的副作用組織在一起(例如創(chuàng)建訂閱及取消訂閱),而不要把它們拆分到不同的生命周期函數(shù)里。

      Hook 使用規(guī)則

      Hook 就是 JavaScript 函數(shù),但是使用它們會有兩個額外的規(guī)則:

      • 只能在函數(shù)最外層調(diào)用 Hook。不要在循環(huán)、條件判斷或者子函數(shù)中調(diào)用。

      • 只能在 React 的函數(shù)組件中調(diào)用 Hook。不要在其他 JavaScript 函數(shù)中調(diào)用。(還有一個地方可以調(diào)用 Hook &mdash;&mdash; 就是自定義的 Hook 中,我們稍后會學(xué)習(xí)到。)

      自定義 Hook

      有時候我們會想要在組件之間重用一些狀態(tài)邏輯。目前為止,有兩種主流方案來解決這個問題:高階組件和 render props。自定義 Hook 可以讓你在不增加組件的情況下達(dá)到同樣的目的。

      前面,我們介紹了一個叫 FriendStatus 的組件,它通過調(diào)用 useState 和 useEffect 的 Hook 來訂閱一個好友的在線狀態(tài)。假設(shè)我們想在另一個組件里重用這個訂閱邏輯。

      首先,我們把這個邏輯抽取到一個叫做 useFriendStatus 的自定義 Hook 里:

      import React, { useState, useEffect } from 'react';
      function useFriendStatus(friendID) {
        const [isOnline, setIsOnline] = useState(null);
        function handleStatusChange(status) {
          setIsOnline(status.isOnline);
        }
        useEffect(() => {
          ChatAPI.subscribeToFriendStatus(friendID, handleStatusChange);
          return () => {
            ChatAPI.unsubscribeFromFriendStatus(friendID, handleStatusChange);
          };
        });
        return isOnline;
      }

      它將 friendID 作為參數(shù),并返回該好友是否在線:

      現(xiàn)在我們可以在兩個組件中使用它:

      function FriendStatus(props) {
        const isOnline = useFriendStatus(props.friend.id);
        if (isOnline === null) {
          return 'Loading...';
        }
        return isOnline ? 'Online' : 'Offline';
      }
      function FriendListItem(props) {
        const isOnline = useFriendStatus(props.friend.id);
        return (
          <li style={{ color: isOnline ? 'green' : 'black' }}>
            {props.friend.name}
          </li>
        );
      }

      每個組件間的 state 是完全獨立的。Hook 是一種復(fù)用狀態(tài)邏輯的方式,它不復(fù)用 state 本身。事實上 Hook 的每次調(diào)用都有一個完全獨立的 state &mdash;&mdash; 因此你可以在單個組件中多次調(diào)用同一個自定義 Hook。

      自定義 Hook 更像是一種約定而不是功能。如果函數(shù)的名字以 use 開頭并調(diào)用其他 Hook,我們就說這是一個自定義 Hook。 useSomething 的命名約定可以讓我們的 linter 插件在使用 Hook 的代碼中找到 bug。

      你可以創(chuàng)建涵蓋各種場景的自定義 Hook,如表單處理、動畫、訂閱聲明、計時器,甚至可能還有更多我們沒想到的場景。我們很期待看到 React 社區(qū)會出現(xiàn)什么樣的自定義 Hook。

      其他 Hook

      除此之外,還有一些使用頻率較低的但是很有用的 Hook。比如,useContext 讓你不使用組件嵌套就可以訂閱 React 的 Context。

      function Example() {
        const locale = useContext(LocaleContext);
        const theme = useContext(ThemeContext);
        // ...
      }

      另外 useReducer 可以讓你通過 reducer 來管理組件本地的復(fù)雜 state

      function Todos() {
        const [todos, dispatch] = useReducer(todosReducer);
        // ...

      感謝你能夠認(rèn)真閱讀完這篇文章,希望小編分享的“React的Hook是什么”這篇文章對大家有幫助,同時也希望大家多多支持億速云,關(guān)注億速云行業(yè)資訊頻道,更多相關(guān)知識等著你來學(xué)習(xí)!

      向AI問一下細(xì)節(jié)

      免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。

      AI