淺談 React 中的 ref 和 useRef

原文作者:Joel Adewole

原文地址:https://refine.dev/blog/react-useref-hook-and-ref/

翻譯:一川

在各種 JavaScript 庫和框架中,React 因其開發人員友好性和支持性而得到認可。

大多數開發人員發現 React 非常舒適且可擴展,因爲它提供了鉤子。鉤子是 React 附帶的內置 API,允許開發人員與 React的狀態和生命週期功能進行交互。鉤子在類內部不起作用,因此它們只能在功能組件中使用。開發人員還可以決定創建自定義鉤子。

React 比大多數 UI 庫更能讓你重新思考設計標準,允許開發人員自定義 UI 組件,例如使用 ReactJSX 的抽象機制而不是典型的 DOM 規範創建視圖。

在本文中,我們將討論 React 鉤子函數 useRef ,使用 ref 訪問 DOM 以及 refuseRef 之間的區別。

什麼是 useRef?

React 中包含的各種鉤子之一是 useRef 鉤子; 它用於引用功能組件中的對象,並在重新渲染之間保留引用對象的狀態。

useRef 有一個名爲 “current” 的屬性,用於隨時檢索引用對象的值,同時還接受初始值作爲參數。您可以通過更新 current 值來更改引用對象的值。

以下是創建引用對象的方法:

import { useRef } from ‘react’

const myComponent = () ={
    const refObj = useRef(initialValue)

    return (
    //…
    )
}

在上面的代碼片段中,我們有一個要在應用程序中引用的對象 refObj ,要訪問值或更新值,我們可以像這樣調用 current 該屬性:

// inside a function
const handleRefUpdate = () ={
    // accessing the referenced object’s value
    const value = refObj.current

    // updating the referenced object’s value
   refObj.current = newValue
}

您應該注意:

使用 ref 訪問 DOM 元素

請記住,DOM 元素也是對象,我們可以使用useRef引用它們。但是現在,我們需要利用另一個名爲 ref

ref 是一個 HTML 屬性,它將引用的對象分配給 DOM 元素。讓我們看看這是如何工作的:

import {useRef} from ‘react’

const myComponent = () ={
    const elementRef = useRef()

    return (
        <input ref={elementRef} type=”text” />
    )
}

在上面的代碼片段中,我們創建了一個新的引用對象,elementRef 並使用屬性 ref 將其分配給輸入標記。我們可以訪問輸入標籤的值並像這樣更新值:

const handleInput = () ={
    //accessing the input element value
   const textValue = elementRef.current.value


   // update the input element value
   elementRef.current.value = “Hello World”
}

Ref 和 useRef 之間的區別

既然我們瞭解了useRefRef工作方式及它們的差異,讓我們看看如何在實際應用程序中使用它們。例如,我們希望爲彈出窗口實現一個點擊離開事件偵聽器。我們可以利用ref訪問彈出窗口的 DOM 元素,並在彈出窗口外單擊時進行偵聽。

在你的 react 應用中,你可以創建一個名爲 “hooks” 的文件夾,這個文件夾將包含自定義鉤子。

在文件夾中創建一個新文件 useClickAway ,並在文件中輸入以下代碼:

import React, { useEffect} from 'react'
 
export default function useClickAway(ref: any, callback: Function) {
   useEffect(() ={
     function handleClickAway(event: any) {
       if (ref.current && !ref.current.contains(event.target)) {
         callback();
       }
     }
 document.addEventListener("mousedown", handleClickAway);
     return () ={
       document.removeEventListener("mousedown", handleClickAway);
     };
   }[ref]);
 };

在上面的代碼片段中,我們創建了一個接受引用對象作爲 ref 和回調函數的自定義鉤子,然後我們執行了一個事件偵聽器來檢查何時單擊鼠標,如果單擊不在當前 ref 上,則我們觸發回調函數。

以下是產品頁面上自定義掛鉤的實現:

import React, { useRef } from "react";
//.. Other importations
export default function Storefront() {
  const targetElement = useRef(null)
  const alertClickAway = () ={
   alert("Clicked outside product 1")
 }
 useClickAway(targetElement, alertClickAway)
 //.. Other functions
 return (
       {//.. Other parts of the application}
       <div class>
         <div class ref={targetElement}>
           <img src="https://i.postimg.cc/G207QNV7/image.png" alt="Product 1" />
           <p>iWatch Series 6</p>
           <div class>
             <button>
               <img src="https://api.iconify.design/flat-color-icons:like.svg?color=%23888888" alt="like" />
             </button>
             <button>
               <img 
                  src="https://api.iconify.design/icon-park:buy.svg?color=%23888888"
                  alt="add" />
            </button>
           </div>
         </div>
 )
}

在上面的代碼片段中,我們有一個店面組件,我們在其中導入了自定義鉤子,然後我們創建了一個新的引用對象 targetElement 並將其分配給產品庫中的 div,然後我們創建了一個回調函數useClickAway,以便在使用ref在產品項外部單擊鼠標時發出警報 targetElement

現在讓我們看看輸出:

Ref 和 useRef 的使用案例

你現在對什麼是ref以及useRef,以及它們的使用有了一定的瞭解。refuseRef兩者都很容易被濫用,會造成使用開銷比較大。現在你可能需要考慮的是何時使用,以及如何儘可能避免使用。

以下是參考的一些用途:

在某些情況下(如下所示),不應使用引用:

import {useRef} from ‘react’

const FunctionalComponent = () ={
    return (
        <h1>Hello World<>
)
}

const myComponent = () ={
         const elementRef = useRef()

    return (
        <FunctionalComponent ref={elementRef} />
    )
}

由於組件 FunctionalComponent 沒有實例,因此上述代碼片段中的 ref 將不起作用。相反,我們可以將其轉換爲FunctionalComponent類組件或在 FunctionalComponent 組件的 forwardRef 中使用。

結論

在本文中,我們討論瞭如何使用 useRef 鉤子創建引用,該鉤子採用初始值並修改引用對象的 “current” 屬性的值以更新其值。

我們看到了如何將 “current” 值與 “ref” 一起使用來訪問 DOM 元素並與其屬互。

我們將介紹如何創建一個接受引用 DOM 元素的自定義鉤子和一個回調函數,以便在應用程序中使用 “ref” 和 “useRef” 來觀察 DOM 元素上的單擊事件。

此外,我們還討論了 “ref” 和 “useRef” 的用例,何時使用它們,何時不使用它們。

在瞭解了ref 以及useRef 如何在不重新渲染父組件的情況下跟蹤和更新可變值之後,您可以通過查看RefsuseRefsReact 的相關官方文檔,來探索更多關於它們的信息或瞭解更多信息,甚至嘗試其他 React 鉤子。

本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源https://mp.weixin.qq.com/s/pHs8w_eEsYj7k9XydBNr4Q