溫馨提示×

溫馨提示×

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

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

React的Hook是什么

發布時間:2022-03-16 13:34:04 來源:億速云 閱讀:191 作者:小新 欄目:開發技術

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


      State Hook

      這個例子用來顯示一個計數器。當你點擊按鈕,計數器的值就會增加:

      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 (等下我們會講到這是什么意思)。通過在函數組件里調用它來給組件添加一些內部 state。React 會在重復渲染時保留這個 state。useState 會返回一對值:當前狀態一個讓你更新它的函數,你可以在事件處理函數中或其他一些地方調用這個函數。它類似 class 組件的 this.setState,但是它不會把新的 state 和舊的 state 進行合并。(我們會在使用 State Hook 里展示一個對比 useState 和 this.state 的例子)。

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

      聲明多個 state 變量

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

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

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

      那么,什么是 Hook?

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

      React 內置了一些像 useState 這樣的 Hook。你也可以創建你自己的 Hook 來復用不同組件之間的狀態邏輯。我們會先介紹這些內置的 Hook。

      Effect Hook

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

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

      例如,下面這個組件在 React 更新 DOM 后會設置一個頁面標題:

      import React, { useState, useEffect } from 'react';
      function Example() {
        const [count, setCount] = useState(0);
        // 相當于 componentDidMount 和 componentDidUpdate:
        useEffect(() => {
          // 使用瀏覽器的 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 時,就是在告訴 React 在完成對 DOM 的更改后運行你的“副作用”函數。由于副作用函數是在組件內聲明的,所以它們可以訪問到組件的 props 和 state。默認情況下,React 會在每次渲染后調用副作用函數 &mdash;&mdash; 包括第一次渲染的時候。

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

      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 的訂閱,然后在后續渲染時重新執行副作用函數。(如果傳給 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,你可以把組件內相關的副作用組織在一起(例如創建訂閱及取消訂閱),而不要把它們拆分到不同的生命周期函數里。

      Hook 使用規則

      Hook 就是 JavaScript 函數,但是使用它們會有兩個額外的規則:

      • 只能在函數最外層調用 Hook。不要在循環、條件判斷或者子函數中調用。

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

      自定義 Hook

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

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

      首先,我們把這個邏輯抽取到一個叫做 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 作為參數,并返回該好友是否在線:

      現在我們可以在兩個組件中使用它:

      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 是一種復用狀態邏輯的方式,它不復用 state 本身。事實上 Hook 的每次調用都有一個完全獨立的 state &mdash;&mdash; 因此你可以在單個組件中多次調用同一個自定義 Hook。

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

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

      其他 Hook

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

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

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

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

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

      向AI問一下細節

      免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

      AI

      亚洲午夜精品一区二区_中文无码日韩欧免_久久香蕉精品视频_欧美主播一区二区三区美女