Skip to content

useRef — DOM Access

useRef — เข้าถึง DOM โดยตรง

Section titled “useRef — เข้าถึง DOM โดยตรง”

useRef ให้คุณ เก็บค่า โดยไม่ทำให้ re-render เมื่อค่าเปลี่ยน (ต่างจาก useState)

import { useRef } from "react"
function FocusInput() {
const inputRef = useRef(null)
function handleClick() {
// เข้าถึง DOM element โดยตรง!
inputRef.current.focus()
}
return (
<>
<input ref={inputRef} type="text" />
<button onClick={handleClick}>Focus</button>
</>
)
}
flowchart LR
    subgraph "useRef Hook"
        %% ใช้ ID เป็นคำง่ายๆ เช่น R, D, A
        R["ref = useRef(null)"] 
        D["&lt;input ref={ref} /&gt;"] 
        A["ref.current.focus()"]

        %% เชื่อมต่อด้วย ID
        R -->|Assign to| D
        D -->|Access via| A
    end

ใช้งาน: เก็บค่าที่ไม่ต้องการ render

Section titled “ใช้งาน: เก็บค่าที่ไม่ต้องการ render”
import { useRef, useState } from "react"
function CounterWithRef() {
const [count, setCount] = useState(0)
const prevCountRef = useRef(0)
function handleClick() {
prevCountRef.current = count // เก็บค่าก่อนเปลี่ยน
setCount(c => c + 1)
}
return (
<div>
<p>Current: {count}</p>
<p>Previous: {prevCountRef.current}</p>
<button onClick={handleClick}>+1</button>
</div>
)
}

ตัวอย่าง: Stopwatch ด้วย useRef

Section titled “ตัวอย่าง: Stopwatch ด้วย useRef”
import { useState, useRef, useEffect } from "react"
function Stopwatch() {
const [time, setTime] = useState(0)
const intervalRef = useRef(null)
const [isRunning, setIsRunning] = useState(false)
useEffect(() => {
if (isRunning) {
intervalRef.current = setInterval(() => {
setTime(t => t + 1)
}, 1000)
}
return () => clearInterval(intervalRef.current)
}, [isRunning])
return (
<div>
<p>Time: {time}s</p>
<button onClick={() => setIsRunning(!isRunning)}>
{isRunning ? "Stop" : "Start"}
</button>
</div>
)
}

เปรียบเทียบ useState vs useRef

Section titled “เปรียบเทียบ useState vs useRef”
Hookใช้เก็บRe-render เมื่อ
useStateค่าที่แสดงใน UIค่าเปลี่ยน
useRefค่าที่ไม่แสดงใน UIไม่ re-render
Avatar whiteCat
useState เปลี่ยน → re-render / useRef เปลี่ยน → ไม่ re-render