useRef

메론맛캔디·2021년 11월 12일
1

바닐라 자바스크립트에서는 DOM 조작을 하기 위해 querySelector나 getElementById를 사용했다. 리액트에서는 DOM 조작을 어떻게 할까?

useRef 란?

.current 프로퍼티로 전달된 인자로 초기화된 변경 가능한 (mutable한) ref 객체를 반환한다. - 이 객체에는 일반 변수 뿐만아니라 DOM을 담을 수도 있다.
반환된 객체는 컴포넌트의 전 life cycle을 통해 유지된다.
useRef는 .current 프로퍼티에 변경가능한 값을 담고있는 객체 라고 생각하면 된다.
.current 프로퍼티를 변경하더라도 리렌더링을 유발하지 않는다. - ref 객체 안의 값은 리액트 생명주기에 독립적이기 때문이다.
값이 변경되더라도 리렌더를 발생시키지 않을 뿐만 아니라, 리렌더 되더라도 값이 유지된다.


예시

애니메이션을 추가하기도 하고, css 스타일을 입힐수도 있고, 자바스크립트 함수를 통해 focus와 같은 내장 메소드를 사용하거나, 이벤트 리스너를 추가할 수도 있다.

프로젝트 리팩토링을 하면서 DOM에 직접 접근해 유저가 인풋 값을 잘못 입력하면 인풋의 border 색상을 변경해주는 작업을 했다.

예시)

import React, { useRef } from 'react';

export default function App() {
  console.log('렌더')

  const inputRef = useRef(); 

  const clickHandler = (e) => {
    e.preventDefault();
    console.log(inputRef.current.value)
    if(inputRef.current.value !== '안녕하세요') inputRef.current.style = 'border: 1px solid rgb(250, 94, 94)'
    else inputRef.current.style = 'border: 1px solid green'
    // inputRef.current.style = 'width:300px; height:300px; background:red;'
  }

  return (
    <form onSubmit={clickHandler}>
      <input ref={inputRef} placeholder='안녕하세요를 입력해주세요'></input>
      <button>확인</button>
    </form>
  );
}

이전에는 useState로만 input을 컨트롤 했는데, ref로도 충분히 컨트롤 가능했다.

useState로 input을 컨트롤할 경우, input이 업데이트 될 때마다 value에 state를 달아놓기 때문에 계속 재 렌더링이 되는 현상이 일어났다.
반면에 useRef로 input을 컨트롤하게 되면, 인풋을 업데이트할때 마다 리렌더링을 하지 않는다.
현재 생각으로는 useRef로 인풋을 컨트롤하는게 form을 클릭하기 전까지 input을 업데이트할 때마다 일어나는 불필요한 리렌더링을 줄일 수 있기 때문에 useRef로 인풋 컨트롤 하는게 더 나아보인다..


참고한 stackoverflow 답변

https://stackoverflow.com/questions/66590082/how-to-prevent-re-rendering-of-components-that-have-not-changed


정리

useRef 훅을 이용하면 ref 객체가 생성되고 .current 프로퍼티로 접근 가능하다.
반환된 ref 객체로 DOM을 접근할 수도 있고, 일반 변수, 즉, 리렌더와 상관 없는 전역변수의 개념이라고 이해할 수있다.
값이 변경되더라도 리렌더를 발생시키지 않을 뿐만 아니라, 리렌더 되더라도 값이 유지된다.
하나의 useRef 객체로 여러 엘리먼트에 생성할 수 없다. 하나의 레퍼런스로 여러 엘리먼트 생성 불가하기 때문.



참고

https://stackoverflow.com/questions/59448579/how-to-use-one-useref-for-multiple-elements-or-how-to-use-useref-for-similar-be

https://stackoverflow.com/questions/65350114/useref-for-element-in-loop-in-react/65350394#65350394

https://sukjae.github.io/posts/using-react-ref-for-multiple-dom-element-control

0개의 댓글