[React] useRef hook 정리

glow_soon·2022년 4월 9일
0

React

목록 보기
41/52

useRef 훅에 대해 잘 모르고 있었는데 정리를 해보았다.

const ref = useRef(value);

우선 useRef를 컴포넌트에서 사용해주면 ref 객체를 반환해준다.

{current: value}

내가 인자로 넣어준 초기값은 ref 안에있는 current에 저장되고, 수정 가능, 언제든지 바꿔줄 수 있다.


쓰는 이유 1

일반적으로 리액트에선 state가 변화되면 리렌더링이 일어나게 되고 컴포넌트의 내부 변수들이 초기화 된다.

하지만 ref를 사용하면 리렌더링이 일어나지않고 변수들의 값들이 유지된다. (불필요한 렌더링 방지) 또한 state가 바뀌었을때 리렌더링이 되지만 ref의 값은 유지된다.

쓰는 이유 2

DOM요소에 접근해서 여러가지 일을 할수있다고 한다.

예를 들어 ref가 없다면 로그인 화면에서 일일이 input창을 클릭하여 입력을 해야하지만, ref를 사용하면 저절로 input창에 포커스가 맞춰진다.


변수 관리

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

function Practice() {
  let [count, setCount] = useState(0);

  console.log("렌더링......");
  return (
    <div>
      <p>State: {count}</p>
      <button
        onClick={() => {
          setCount(count + 1);
        }}
      >
        증가
      </button>
    </div>
  );
}

export default Practice;

콘솔창에서 보이는것처럼 state를 사용해서 변수의 값을 관리하면 값이 바뀔때 마다 렌더링이 된다.


useRef를 사용한다면 어떻게 될까?

ref의 값을 관리해주는 버튼을 하나더 만들었다.

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

function Practice() {
  let [count, setCount] = useState(0);
  let countRef = useRef(0);

  console.log(countRef);

  console.log("렌더링......");
  return (
    <div>
      <p>State: {count}</p>
      <button
        onClick={() => {
          setCount(count + 1);
        }}
      >
        State 올리는 버튼
      </button>

      {/*-------------useRef-----------------*/}
      <p>Ref: {countRef.current}</p>
      <button
        onClick={() => {
          countRef.current = countRef.current + 1;
          console.log("Ref: ", countRef.current);
        }}
      >
        Ref 올리는 버튼
      </button>
    </div>
  );
}

export default Practice;

Ref의 값을 콘솔 창에서 확인해 카운트가 잘 되는것은 보이지만 버튼을 아무리 눌러도 화면의 값은 변화하지 않는다. 당연히 ref를 사용했기 때문에 리렌더링이 일어나지 않기 때문이다.

state 올리는 버튼을 눌러야 리렌더링이 되기때문에 웹상에서 확인 할 수 있었다.


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

function Practice() {
  const [rerenderer, setRenderer] = useState(0); // 렌더링 담당
  const countRef = useRef(0);
  let countVar = 0;

  const doRendering = () => {
    setRenderer(rerenderer + 1);
  };
  const increaseRef = () => {
    countRef.current = countRef.current + 1;
    console.log("Ref: ", countRef.current);
  };
  const increaseVar = () => {
    countVar = countVar + 1;
    console.log("var: ", countVar);
  };

  return (
    <div>
      <p>Ref: {countRef.current}</p>
      <p>Var: {countVar}</p>
      <button onClick={doRendering}>렌더링</button>
      <button onClick={increaseRef}>Ref 올리기</button>
      <button onClick={increaseVar}>Var 올리기</button>
    </div>
  );
}

export default Practice;

이번에는 Ref를 올리는 버튼과 일반 let변수를 올려주는 버튼을 만들어 각각 카운팅하고 콘솔창에서 확인해 보았다. 화면상에 렌더링은 되지 않을것이기 때문에 렌더링 담당 버튼도 만듬
렌더링 버튼을 눌러보았다


Ref의 값은 잘 나왔는데 일반 let 변수의 값은 나타나지 않았다! 띠용??????? 이유가 무엇일까

컴포넌트가 렌더링이 된다는것은 컴포넌트를 나타나는 함수가 다시 불린다는것임, 함수가 불리면 불릴때마다 함수 내부의 변수들이 다시 초기화 되기때문!!!!!! 따라서 countVar 변수는 계속해서 0으로 초기화 됬기 때문이다.

하지만 Ref는 아무리 컴포넌트가 렌더링되도 값을 유지해준다. Ref의 값은 컴포넌트의 전 생애주기를 통해 유지되기 때문

useRef는 변화는 감지해야하지만 그 변화가 렌더링을 발생시키면 안되는 어떤 값을 다룰때 유용하다.


DOM 요소 접근

const ref = useRef(value)

<input ref={ref} />

접근 하고자 하는 태그에 ref 속성으로 넣어주기만 하면 해당 요소에 접근가능하다.

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

function Practice() {
  const inputRef = useRef();

  return (
    <div>
      <input placeholder="username" />
      <button>로그인</button>
    </div>
  );
}

export default Practice; 


ref를 사용하지 않았기때문에 input태그에 포커스가 맞춰져있지 않은 상태이다.

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

function Practice() {
  const inputRef = useRef();

  useEffect(() => {
    inputRef.current.focus();
  }, []);
  
  return (
    <div>
      <input ref={inputRef} placeholder="username" />
      <button>로그인</button>
    </div>
  );
}

export default Practice;

focus가 맞춰지길 원하는 태그의 ref 속성에 선언한 ref를 넣어주고, useEffect 훅을 통해 페이지가 렌더링 되었을 때 inputRef.current.focus()로 DOM요소에 접근하게 하면 된다.


페이지가 렌더링 되었을때 자동으로 input 태그에 포커스가 맞춰진 모습이다.

https://www.youtube.com/channel/UCDfJ2rNZsANU6ZNYNlzDJ5Q 에서 배운 내용을 정리한 글입니다.

profile
나는야 코린이

0개의 댓글