S3. useRef

Haizel·2023년 2월 13일
0

Front-End Developer 되기

목록 보기
53/70
post-thumbnail

react를 공부하면서, react 애플리케이션을 만들 때 → DOM을 직접 조작하는 것은 지양해야 한다고 배웠다.
헌데 개발을 하다보면 DOM을 직접 건들여야하는 상황도 있는데 → 이때 사용할 수 있는 것이 바로 useRef라는 Hook 함수이다.

01. DOM reference를 잘 활용할 수 있는 useRef


  • react론 할 수 없는, 아래와 같이 DOM 엘리먼트의 주소값을 활용해야 하는 경우 useRef 를 활용한다.

    focus
    text selection
    media playback
    애니메이션 적용
    d3.js, greensock 등 DOM 기반 라이브러리 활용

    ⇒ React는 위와 같은 예외적인 상환에서 useRef로, DOM노드, 엘리먼트, 그리고 react 컴포넌트 주소값을 참조할 수 있다.

    1️⃣ 주소값을 활용하기 위해 다음과 같이 코드를 작성할 수 있다.

    • 주소값은 컴포넌트가 re-render되어도 바뀌지 않는다.
const 주소값을_담는_그릇 = useRef(참조자료형)
// 이제 주소값을_담는_그릇 변수에 어떤 주소값이든 담을 수 있습니다.
return (
    <div>
      <input ref={주소값을_담는_그릇} type="text" />
        {/* React에서 사용 가능한 ref라는 속성에 주소값을_담는_그릇을 값으로 할당하면*/}
        {/* 주소값을_담는_그릇 변수에는 input DOM 엘리먼트의 주소가 담깁니다. */}
        {/* 향후 다른 컴포넌트에서 input DOM 엘리먼트를 활용할 수 있습니다. */}
    </div>);

2️⃣ 주소값이 바뀌지 않는 특성을 활용해, 제한된 상황에서 useRef를 활용할 수 있다.

function TextInputWithFocusButton() {
  const inputEl = useRef(null);
  const onButtonClick = () => {
  // `current` points to the mounted text input element
    inputEl.current.focus();
  };
  return (
    <>
      <input ref={inputEl} type="text" />
      <button onClick={onButtonClick}>Focus the input</button>
    </>);
}

🚨 주의사항

제시된 상황을 제외한 경우는 대부분 기본 react문법을 벗어나 useRef를 남용하는 것이 부적절하고, react의 특장점인 ‘선언형 프로그래밍’ 원칙에 위배되므로 → 조심해 사용해야 한다.

💡. useRef에 대한 React 공식문서


const refContainer = useRef(initialValue);
  • useRef.current 프로퍼티로 전달된 인자(initialValue)로 초기화된 변경 가능한 ref 객체를 반환한다.
  • 반환된 객체는 컴포넌트의 전 생애주기를 통해 유지된다.

❗️일반적인 useRef 케이스 : 자식에게 명령적으로 접근하는 경우

function TextInputWithFocusButton() {
  const inputEl = useRef(null);
  const onButtonClick = () => {
    // `current` points to the mounted text input element
    inputEl.current.focus();
  };
  return (
    <>
      <input ref={inputEl} type="text" />
      <button onClick={onButtonClick}>Focus the input</button>
    </>
  );
}
  • 본질적으로 useRef는 .current프로퍼티에 변경 가능한 값을 담고 있는 “상자”와 같다.
이 코드는 useRef를 통해서 input태그에 focus를 주는 코드이다.
useRef를 쓰면 .current 라는 객체에 ref로 지정한 엘리먼트의 DOM값을 확인할 수 있고 조종할 수 있다.

또한 useRef의 두 번째 사용법은 특정 변수를 담는 그릇으로 활용하는 것이다.
useRef로 변수를 관리하게 되면 그 변수가 업데이트 된다고 해서 컴포넌트가 리렌더링 되지 않는다는 특징을 가진다.
이 특징을 활용해, 굳이 리렌더링할 필요가 없는 변수라면 -> useRef()로 관리해주는 것이 효율적이다.

대표적으로 useRef()를 변수로 활용하는 경우는 다음과 같다.
1)setTimeout, setInterval을 통해 만들어진 id
2)scroll 위치
3)배열에 새 항목을 추가할 때 필요한 고유값 key

❗️DOM 접근 방식과 비교해보자.

*DOM에 접근하는 방법으로 refs를 사용했다고 가정해보자.
<div ref={myRef} />
를 사용해 react로 ref 객체를 전달한다면?
-> react는 노드가 변경될 때마다 변경된 DOM 노드에 그것의 .current 프로퍼티를 설정할 것이다.

**However,**
ref 속성보다 useRef()가 더 유용하다.
=> useRef()는 클래스에서 인스턴스 필드를 사용하는 방법과 유사한데, "어떤 가변값을 유지하는데  편리"하다.

**Because,** 
useRef()가 순수 자바스크립트 객체를 생성하기 때문이다.
=> useRef(){current: ...} 객체 자체를 생성하는 것이 유일한 차이점이라면,
=> useRef()는 매번 랜더링할 때 동일한 ref 객체를 제공한다.

**주의해라,**
useRef()는 내용이 변할 때 그것을 알려주지 않는다.
그리고 .current 프로퍼티를 변형하는 것은 리렌더링을 발생하지 않는다.
따라서 React가 DOM 노드에 ref를 attach하거나 detach할 때, 어떤 코드를 실행하고 싶다면 
 -> 콜백 ref를 대신 사용해라.

02. useRef 예제


🔨 1. focus

https://codesandbox.io/s/patient-worker-3kzhd?from-embed

🔨 2. media playback

https://codesandbox.io/s/priceless-sanderson-kx77s?from-embed

profile
한입 크기로 베어먹는 개발지식 🍰

0개의 댓글