[React]-공식문서-Ref로 값 참조하기

Kng_db·2023년 4월 4일
0

Ref로 값 참조하기

컴포넌트가 특정 정보를 '기억'하도록 하고 싶지만 해당 정보가 새 렌더링을 트리거하지 않도록 하려는 경우 ref를 사용할 수 있습니다.

학습 내용

  • 컴포넌트에 ref를 추가하는 방법
  • ref 값을 업데이트하는 방법
  • state와 ref의 차이점
  • ref를 안전하게 사용하는 방법

컴포넌트에 ref 추가하기

리액트에서 useRef Hook을 가져와서 컴포넌트에 ref를 추가할 수 있습니다:

컴포넌트 내부에서 useRef Hook을 호출하고 참조할 초기값을 인자로 전달하십시오. 예를 들어,값 0은 ref에 대한 초기값입니다:

useRef는 다음과 같은 객체를 반환합니다:

ref.current 속성을 통해 해당 ref의 현재 값에 액세스할 수 있습니다. 이 값은 의도적으로 변경 가능하므로 읽기와 쓰기가 모두 가능합니다. React가 추적하지 않는 컴포넌트의 비밀 주머니와 같습니다. (이것이 바로 React의 단방향 데이터 흐름에서 "탈출구"가 되는 이유입니다. 아래에서 자세히 설명합니다!)

여기서 버튼은 클릭할 때마다 ref.current를 증가시킵니다:

여기서의 ref는 숫자를 가리키고 있지만, state와 마찬가지로 문자열, 객체, 함수 등 무엇이든 가리킬 수 있습니다. state와 달리 ref는 current 속성을 읽고 수정할 수 있는 일반 JavaScript 객체입니다.

컴포넌트는 ref가 증가할 때마다 리렌더링되지 않는다는 점에 유의하세요. state와 마찬가지로 ref는 리렌더링 사이에 React에 의해 유지됩니다. state를 설정하면 컴포넌트가 다시 렌더링됩니다. 반면 ref를 변경하면 그렇지 않습니다!

렌더링에 정보가 사용되는 경우 해당 정보를 state로 유지하세요. 이벤트 핸들러만 정보를 필요로 하고 변경해도 다시 렌더링할 필요가 없는 경우, ref를 사용하는 것이 더 효율적일 수 있습니다.


ref와 state의 차이점

어쩌면 항상 state 설정자 함수를 사용하지 않고도 변이할 수 있기 때문에 ref가 state보다 덜 “strict”하다고 생각할 수 있습니다. 그러나 대부분의 경우 state를 사용하길 원할 것입니다. ref는 자주 사용하지 않는 "탈출구"입니다. state와 ref를 비교하면 다음과 같습니다:

refs

  • useRef(initialValue) return {current:initialValue}
  • 변경 시 리렌더링이 트리거되지 않습니다.
  • Mutable - 렌더링 프로세스 외부에서 current 값을 수정하고 업데이트할 수 있습니다.
  • 렌더링 중에는 current 값을 읽거나 쓰지 않아야 합니다.

state

  • useState(initialValue) 는 state 변수의 현재 값과 state 설정자 함수 ([value, setValue])를 반환합니다.
  • 변경 시 리렌더링을 트리거합니다.
  • Immutable - state setting 함수를 사용하여 state 변수를 수정해 리렌더링을 대기열에 추가해야 합니다.
  • 언제든지 state를 읽을 수 있습니다. 그러나 각 렌더링에는 변경되지 않는 자체 state snapshot이 있습니다.

  • [DEEP DIVE] ref는 내부에서 어떻게 작동하나요?

useState와 useRef는 모두 React에서 제공하지만, 원칙적으로 useRef는 useState 위에 구현될 수 있습니다. React 내부에서 useRef는 다음과 같이 구현된다고 상상할 수 있습니다

첫 번째 렌더링 중에 useRef{ current: initialValue }를 반환합니다. 이 객체는 React에 의해 저장되므로 다음 렌더링 중에 동일한 객체가 반환됩니다. 이 예제에서 state setter가 어떻게 사용되지 않는지 주목하세요. useRef는 항상 동일한 객체를 반환해야 하기 때문에 불필요합니다!

React는 충분히 일반적인 상황이라 판단하고 내장된 버전의 useRef를 제공합니다. ref를 설정자가 없는 일반 state 변수라고 생각하면 됩니다. 객체지향 프로그래밍에 익숙하다면 인스턴스 필드를 떠올릴 수 있는데, this.something 대신 somethingRef.current를 사용하면 됩니다.


참조를 사용해야 하는 경우

일반적으로 ref는 컴포넌트가 React로부터 "한 발 밖으로 나와서" 컴포넌트의 형상에 영향을 주지 않는 외부 API(브라우저 API 등)과 통신해야 할 때 사용합니다. 다음은 이러한 상황 중 일부입니다:

컴포넌트에 일부 값을 저장해야 하지만 렌더링 로직에는 영향을 미치지 않는 경우 ref를 선택하세요.


ref 모범 사례

다음 원칙을 따르면 컴포넌트의 예측 가능성을 높일 수 있습니다:

  • ref를 탈출구로 취급하세요. ref는 외부 시스템이나 브라우저 API로 작업할 때 유용합니다. 애플리케이션 로직과 데이터 흐름의 대부분이 ref에 의존하는 경우 접근법을 다시 생각해보세요

  • 렌더링 중에는 ref.current를 읽거나 쓰지 마세요. 렌더링 중에 일부 정보가 필요하다면 state를 대신 사용하세요. React는 ref.current가 언제 변경되는지 모르기 때문에 렌더링 중에 읽어도 컴포넌트의 동작을 예측하기 어렵습니다. (유일한 예외는 첫 번째 렌더링 중에 ref를 한 번만 설정하는 if (!ref.current) ref.current = new Thing()과 같은 코드입니다).

React state의 제한은 ref에는 적용되지 않습니다. 예를 들어 state는 모든 렌더링에 대해 스냅샷처럼 작동하며 동기적으로 업데이트되지 않습니다. 하지만 ref의 현재 값을 변이하면 즉시 변경됩니다:

이는 ref 자체가 일반 자바스크립트 객체이므로 자바스크립트 객체처럼 동작하기 때문입니다.

또한 ref로 작업할 때 변이(mutation)를 피하는 것에 대해 걱정할 필요가 없습니다. 변이하는 객체가 렌더링에 사용되지 않는 한, React는 ref나 그 콘텐츠로 무엇을 하든 상관하지 않습니다.


Ref와 DOM

ref는 모든 값을 가리킬 수 있습니다. 그러나 ref의 가장 일반적인 사용 사례는 DOM 요소에 액세스하는 것입니다. 예를 들어 프로그래밍 방식으로 input에 focus를 맞추고자 할 때 유용합니다. <div ref={myRef}>와 같이 JSX의 ref 어트리뷰트에 ref를 전달하면 React는 해당 DOM 엘리먼트를 myRef.current에 넣습니다. 이에 대한 자세한 내용은 Manipulating the DOM with Refs에서 확인할 수 있습니다.


요약

  • Ref는 렌더링에 사용되지 않는 값을 유지하기 위한 탈출구입니다. 자주 필요하지 않습니다.
  • ref는 current라는 단일 프로퍼티를 가진 일반 자바스크립트 객체로, 읽거나 설정할 수 있습니다.
  • useRef Hook을 호출하여 React에 ref를 제공하도록 요청할 수 있습니다.
  • state와 마찬가지로 ref를 사용하면 컴포넌트의 리렌더링 사이에 정보를 유지할 수 있습니다.
  • state와 달리 ref의 current 값을 설정해도 리렌더링이 트리거되지 않습니다.
  • 렌더링 중에는 ref.current를 읽거나 쓰지 마세요. 이렇게 하면 컴포넌트를 예측하기 어렵습니다.
profile
코딩 즐기는 사람

0개의 댓글