[React] useRef를 사용하여 특정 DOM 선택 & 컴포넌트 안에 변수를 관리해보자

장성우·2022년 12월 14일
0
post-thumbnail

1. Ref가 무엇일까?

리액트에서 Ref는 그냥 참조를 의미한다. (reference의 준말)

  • ref의 가장 기본적인 기능은 다른 DOM 요소에 접근해 그것들로 작업할 수 있게 해주는 기능이다.
  • HTML 작성 시 DOM요소에 이름을 달 경우 id를 사용한다. 이처럼 리액트에서도 DOM을 직접 접근하기 위한 방법이 있는데 이를 ref라고 부른다.

2. Ref를 사용해야 할 때

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

State vs Ref

  • State의 변화 → 컴포넌트 렌더링 → 컴포넌트 내부 변수들 초기화
  • Ref의 변화 → 렌더링 X → 변수들의 값이 유지됨
    • State의 변화 → 컴포넌트 렌더링 → Ref의 값은 초기화되지 않음

useRef를 사용하여 ref 연결하기

// App.js
import { useRef } from 'react';

function App() {
    const inputEl = useRef(null);

    const onButtonClick = (e) => {
        e.preventDefault();
        console.log(inputEl);
    };

    return (
        <form>
            <input ref={inputEl} type="text" />
            <button onClick={onButtonClick}>보내기</button>
        </form>
    );
}

export default App;

2. DOM 요소에 접근할 때

Javascript에서 querySelector, getElementById같은 DOM API를 리액트에서도 가끔씩 사용을 해줘야 할 때가 있다 (스크롤바 위치 가져오기, 포커스 설정 등). 그럴 때 useRef Hook 함수를 사용한다.

useRef를 사용하여 input에 포커스가 잡히도록 구현

// App.js
import { useEffect, useRef } from 'react';

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

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

    const greetHandler = () => {
        alert(`안녕하세요. ${inputRef.current.value}`);
    };

    return (
        <div>
            <input type="text" placeholder="사용자 이름" ref={inputRef} />
            <button onClick={greetHandler}>로그인</button>
        </div>
    );
};

export default App;

끝으로 사용사례 정리

공식문서에서 발췌한 Ref의 바람직한 사용 사례.

  • 포커스, 텍스트 선택영역, 혹은 미디어의 재생을 관리할 때.
  • 애니메이션을 직접적으로 실행시킬 때.
  • 서드 파티 DOM 라이브러리를 React와 같이 사용할 때.

내 경우

  • 폼 태그의 데이터 제출용: ref Hook 사용
  • 유효성 검증을 위해 매 입력마다 값이 필요한 경우: state Hook을 사용

예) input 태그에서 사용자가 입력한 내용일 관리할 때 state로 관리하는 방법이 있다. 하지만 state로 관리를 하면 매번 키를 누를 때마다 사용자로부터 얻은 값을 업데이트하고, 그것을 state에 저장하고 그 state를 input에 다시 공급한다. 그리고 나중에 그 state를 사용해 인풋을 재설정하고 데이터가 필요한 곳으로 보내기도 한다.

물론 이 방법이 나쁜것은 아니지만 폼 태그에서 제출할 때만 필요한 경우에는 좀 과한 프로세스로 느껴진다. 이 경우 ref를 사용할 수가 있다.

0개의 댓글