Lala Code

Lala 的前端大補帖,歡迎一起鑽研前端技術😊

0%

【DAY 20】useRef 儲存資料與指定 DOM 元素

cover

認識 useRef

在寫原生 JavaScript 時,我們常常會用 document.querySelector 來獲取 DOM 元素,在 React 你可以使用 useRef 直接在元素上做綁定,已達到指定 DOM 的行為動作。除了訪問 DOM,useRef 還可以用來儲存資料、抓取以前的值。

useRef 會自己建立一個 mutable ref object,裡面會有一個 current 屬性設為相應的 DOM 節點或資料,不會隨著元件 re-render 被重新創造,所以 useRef 每次都會返回同一個 ref object

Mutable object:以傳址(by reference)方式被儲存,物件被創造後,參考固定,但參考的記憶體內容可以改變,如 JavaScript 的參考型別 Object、Array、Function 等

Immutable object:以傳值(by value)方式被儲存,物件被創造後,其 value 無法被改變,如 JavaScript 的原始型別 number、string、null、undefined、boolean 等


useRef 使用方法

  • 從 react 中載入 useRef
  • 設定 useRef 初始值
  • 抓取 useRef 的值


1. 從 react 中載入 useRef

1
import { useRef } from "react";



2. 設定 useRef 初始值

1
const refContainer = useRef(initialValue);

refContainer 為自定義變數

initialValue 為初始值,可以為任何值





3. 抓取 useRef 的值

1
refContainer.current

.current 取得 ref object 的值,實際操作會在使用情境做說明





useRef 使用情境

  • 指定 DOM 元素做操作
  • 計算渲染次數
  • 儲存不會導致畫面渲染的資料 (如抓取以前的值)


1. 指定 DOM 元素做操作

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
import { useEffect, useRef } from "react";

const App = () => {
const myInput = useRef();

useEffect(() => {
myInput.current.focus();
}, []);

return (
<div>
<label>Name:</label>
<input type="text" ref={myInput} />
</div>
);
};

export default App;

情境說明:

  • 指定 input 在一開始渲染後游標會自動跑到輸入欄位

useRef

操作說明:

  • 在指定的 input 加上 ref 屬性,自訂變數名稱
  • 創建 useRef 指向自訂變數名稱
  • 從 .current 獲取 dom元素 <input type="text" />,並在 useEffect 操作 .focus 動作

    更新 useRef 是 side Effect 的行為,因此要在 useEffect 或 event handler 裡執行




2. 計算渲染次數

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
import { useRef, useEffect, useState } from "react";

const App = () => {
const [name, setName] = useState("");

const renderCount = useRef(1);

useEffect(() => {
renderCount.current += 1;
});

return (
<>
<input
type="text"
value={name}
onChange={(e) => {
setName(e.target.value);
}}
/>
<p>I rendered {renderCount.current} times!</p>;
</>
);
};

export default App;

情境說明:

  • 在輸入框輸入文字,useRef 會計算每次渲染的次數

useRef

操作說明:

  • 設定一個綁定 useState 的輸入框
  • 創建 useRef,初始值為 1
  • useEffect 沒有 dependencies,所以每次 re-render 時都會執行 renderCount.current += 1



3. 儲存不會導致畫面渲染的資料

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
import { useState, useRef, useEffect } from "react";

const App = () => {
const [name, setName] = useState("");
const previousName = useRef(name);

useEffect(() => {
previousName.current = name;
console.log(previousName.current);
}, [name]);

return (
<div>
<input
type="text"
value={name}
onChange={(e) => setName(e.target.value)}
/>

<p>
My name is <span>{name}</span>
</p>

<p>
My previous name is
<span>{previousName.current}</span>
</p>
</div>
);
};

export default App;

情境說明:

  • 輸入框輸入文字後,會顯示出輸入後、上一次輸入的文字

useRef

操作說明:

  • 設定一個綁定 useState 的輸入框
  • 創建 useRef,初始值為 name,也就是空字串
  • 所以每次更新 name 時都會執行 previousName.current = name

ref 與 state 的差異就是 ref 更新不會觸發 re-render,state 才會,所以即使 ref 已更新成輸入後的 name,畫面也不會隨著渲染,會在下一次 useState re-render 後出現




結語

之前比較常看到 useRef 用來操作 dom,原來也可以定義不會導致畫面重新渲染的資料,理解了 ref 跟 state 的使用上是差在 ref 不會觸發 re-render,今天到這邊結束,明天再繼續吧!!





Reference

Learn useRef in 11 Minutes
一個範例讓你搞懂useState, useRef, useEffect | 5分鐘快速教學


本文為 IT 鐵人賽系列文 你 React 了嗎? 30 天解鎖 React 技能




Hey!想學習更多前端知識嗎?

最近 Lala 開了前端課程 👉【實地掌握RWD - 12小時新手實戰班】👈
無論您是 0 基礎新手,又或是想學 RWD 的初學者,
我們將帶你從零開始,深入了解並掌握 RWD 響應式網頁設計的核心技術,快來一起看看吧 😊



🚀線上課程分享

線上課程可以加速學習的時間,省去了不少看文件的時間XD,以下是我推薦的一些課程
想學習更多關於前後端的線上課程,可以參考看看。

Hahow

Hahow 有各式各樣類型的課程,而且是無限次數觀看,對學生或上班族而言,不用擔心被時間綁住



六角學院

如果你是初學者,非常推薦六角學院哦!
剛開始轉職也是上了六角的課,非常的淺顯易懂,最重要的是,隨時還有線上的助教幫你解決問題!


Udemy

Udemy 裡的課程非常的多,品質普遍不錯,且價格都滿實惠的,CP值很高!
也是很多工程師推薦的線上課程網站。
❤️