React/개념

UseRef - 값을 변경해도 렌더링이 일어나지 않도록

_JHS_ 2024. 3. 4. 14:25

사용법

초기화 : const ref = useRef(value); 

데이터가 저장되는 형태는 Object 다 => {current : value }

 

값 변경 : ref.current = newValue  // {current : newValue}

 

언제 쓸까?

1. 변화는 감지해야 하지만 그 변화가 랜더링을 발생시키지 않도록 할 경우 useRef를 사용한다.

2. useRef를 사용해서 DOM 속성에 접근할 수 있다. ( ex. input 태그에 focus하도록 )

state와 ref 차이점

state를 변경할 경우 렌더링이 일어나지만, ref를 변경할 경우 Component 가 렌더링이 일어나지 않는다.

 

import React from "react";
import { useState } from "react";
import { useRef } from "react";

function AppRef(){
    const refNum = useRef(0);
    const [stateNum, setStateNum] = useState(0);

    console.log("렌더링 발생");

    const increaseStateNum = ()=>{
        setStateNum((stateNum)=>(stateNum+1));
    }
    
    const increaseRefNum = ()=>{
        refNum.current = refNum.current+1;
        console.log(`refNum : ${refNum.current}`);
    }
    return(
        <>
            <h1>refNum:{refNum.current}</h1>
            <h1>stateNum:{stateNum}</h1>
            <button onClick={increaseRefNum}>refNum + 1 </button>
            <button onClick={increaseStateNum}>stateNum + 1 </button>
        </>
    )
}

export default AppRef;

refNum + 1을 3번 누른 후 , stateNum + 1 을 눌렀을 때 렌더링이 발생하면서 값이 3과 1로 변경됨.

 

 

전역변수와 ref 차이점

state의 변화에 의해서 Component 가 다시 렌더링이 일어난 경우, ref값은 유지된다.(refNum+1 을 3번 누른 후 화면에는 여전히 0으로 나오다가 state+1을 한 순간, refNum.current가 3을 유지하면서 화면에 렌더링 된다.)

전역변수는 다시 초기값으로 초기화가 된다.ㅇ

 

 

refNum + 1 을 2번, num + 1을 2번 누른 후, stateNum +1 을 눌렀을 때 refNum의 값만 유지가 된다.

 

 

DOM 접근

Login 상황에서 사용자가 아이디를 바로 칠 수 있도록 input태그를 focus해두는 예시.

이 외에도 오디오 태그에 접근하거나 여러 DOM 에 접근해서 ref를 통해서 제어할 수 있다.

import React,{useEffect, useRef} from "react";

function Login(){
    const inputRef = useRef();
    
    useEffect(()=>{
        inputRef.current.focus();
    },[])

    const login = ()=>{
        alert(`환영합니다 ${inputRef.current.value}`)
        inputRef.current.focus();
        inputRef.current.value = '';
    }
    return(
        <div className="login">
            <input ref={inputRef} type="text" placeholder="아이디" />
            <button onClick={login}>로그인</button>
        </div>
    )
}

export default Login;

처음 페이지를 들어가자마자 input 태그에 focus가 되어있다.