ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [React] ref란? (feat. DOM API를 쓰면 안되는 이유)
    ReactJS 2022. 11. 30. 19:08

    ref란?

    HTML을 작성할 때, div 등의 DOM 요소에 이름을 달 경우 <div id="my-id"> 와 같이 id를 사용한다. 이렇게 하면 특정한 id에 해당하는 DOM 요소에만 스타일을 따로 적용하거나, 자바스크립트에서 해당 DOM 요소에 접근하여 여러 가지 작업을 할 수 있다. HTML을 작성할 때 이렇게 id를 붙이는 것처럼, 리액트에서도 DOM을 선택해 직접 접근하기 위해 ref를 사용한다.

     

    React에서 state로만 해결할 수 없고, DOM을 반드시 직접 건드려야 할 때 사용한다. 예를 들어 특정 input에 focus 주기, 스크롤 박스 조작, Canvas 요소에 그림 그리기 등 이 있다.

     

    왜 DOM API를 쓰면 안될까?

    document.getElementsByClassName과 같은 자바스크립트 문법을 쓰는 것이 아니라 ref를 쓰는 이유는 무엇일까? Ref는 특정 DOM 요소를 가져올때 더 신뢰할 만하기 때문이다. 라이프 사이클에 따라 DOM 요소를 가져오지 못하는 경우가 있는데, 이런 예측하지 못한 상황으로 인해 DOM 요소를 가져오지 못한다면 로직에 따라 큰 결함으로 이어질 수 있다. 또한 HTML에서 DOM요소에 이름을 달때 쓰이는 id는 유일해야 하기 때문에 컴포넌트 재사용을 한다면 중복될 가능성이 농후하다. 반면에 Ref는 전역적으로 작동하지 않고 컴포넌트 내부에서만 작동한다.

     

    컴포넌트가 하나가 아닌 여러개가 생성되는 경우 우리는 id나 class로 특정해서 원하는 DOM 요소를 가져올수 있을것인가? 의문을 던진다면 쉽지 않을것이다. DOM 요소를 특정할 수 있도록 관심 영역을 특정 컴포넌트로 제한하는 역할을 Ref가 할 수 있다.

     

    Ref는 컴포넌트 라이프 사이클(마운트와 언마운트) 내에서 유지되는 변경이 가능한 변수이며, 변수가 변할 때 렌더링이 추가로 되지 않는다. 이와 반대로 state는 컴포넌트 라이프 사이클 내에서 유지되는 변경이 가능한 변수이지만, state가 변할 때는 렌더링이 발생한다. 즉 ref를 활용하면 전체 컴포넌트를 렌더링 시키지 않고, dom에만 접근하여 내가 원하는 효과를 주는게 가능해진다.

     

    실제로 input 박스에 적용해본 ref

    const inputRef = useRef([]);
    
    function clearInput() {
        inputRef.current[0].value = "";
        inputRef.current[1].value = "";
        setTempTitle("");
        setTempContent("");
    }
    <div className="inputContent">
      <span className="inputText">제목</span>
      <input
        className="inputBox"
        onChange={(e) => {
          setTempTitle(e.target.value);
        }}
        // 이렇게 할 수도 있지만 onChange에다가 넘겨서 할 수 있다.
        ref={(element) => (inputRef.current[0] = element)}
      />
      <span className="inputText">내용</span>
      <input
        className="inputBox"
        onChange={(e) => {
          setTempContent(e.target.value);
        }}
        ref={(element) => (inputRef.current[1] = element)}
      />
    </div>

    'ReactJS' 카테고리의 다른 글

    [React] 리액트 Virtual DOM  (0) 2022.11.30
    [React] 컴포넌트와 렌더링  (0) 2022.11.30
    [ReactJS] useEffect, Cleanup  (0) 2022.10.07
    [ReactJS] props, memo  (0) 2022.10.06
    [ReactJS] 리액트로 분/시간, Km/Miles 변환기 만들기  (0) 2022.10.05
Designed by Tistory.