렌더링과는 별개로 변수를 사용하거나 DOM 요소에 접근할 때 사용되는 기능이다.
useState 의 경우 값을 바꿀 때 화면도 렌더링 되지만, useRef는 렌더링과 관계없이 변경 가능한 값들을 가질 수 있다.
=> Ref는 State와 비슷하게 어떠한 값을 저장해두는 저장 공간으로 활용된다.
useRef는 HTML 요소에 직접 접근할 때 유용하게 사용될 수 있다. 예를 들자면 특정 input 에 포커스를 설정하거나, 스크롤 동작을 제어할 때 사용된다.
import React, { useRef } from "react";
function InputFocus() {
const inputRef = useRef(null);
const focusInput = () => {
inputRef.current.focus();
};
return (
<div>
<input ref={inputRef} type="text" />
<button onClick={focusInput}>Focus Input</button>
</div>
);
}
이 코드는 useRef를 사용해서 input 요소의 참조를 생성하고, 버튼 클릭 시 해당 input 요소에 포커스를 맞추는 기능을 한다. 그래서 왜 useRef 가 DOM 요소에 직접적인 조작이 필요한 경우에 유용하게 사용될 수 있느냐??
왜냐하면 useRef를 통해 생성된 참조 객체 를 통해 DOM 요소에 직접 접근할 수 있기 때문이다.
참조객체는 무엇이냐?
참조 객체 는 React 에서 useRef 훅을 사용해서 생성된 객체를 말한다. 이 객체는 알다싶이 렌더링 사이클과 독립적으로 유지되는 변경 가능한 값을 저장할 때 사용된다.
current 프로퍼티를 통해 값에 접근useRef 로 생성된 객체는 {current : ...} 형태를 가지고 있기에 current 프로퍼티에 저장된 값에 접근 하거나 변경할 수 있다.useRef는 이러한 특징들 때문에 DOM 조작에 유용한 것이다 특정 DOM 요소를 직접 조작할 때 렌더링 흐름과 충돌하지 않고도 필요한 조작을 수행할 수 있게끔, 안전하고 간단하게 DOM 에 접근할 수 있도록 해준다.
필요한 경우에만 사용 : Ref 는 직접적인 DOM 접근이 필요할 때 사용해야 한다. 포커스 설정, 텍스트 선택 , 미디어 재생제어와 같이 선언적인 방식으로 해결할 수 없는 작업에 사용한다.
컴포넌트 내부에서만 사용 : Ref는 컴포넌트 내부에서만 사용하고 외부로 노출시키지 않는다. 컴포넌트의 내부 구현을 외부로 유출시키면 컴포넌트의 재사용성과 유지보수성이 떨어지기 때문
상태 업데이트에는 사용하지 않기 : Ref를 사용해 상태 업데이트와 같은 리액트의 데이터 흐름을 우회하는 것은 피해야한다.
Ref 남용 방지 : 모든 상호 작용이나 DOM 조작에 Ref 를 사용하는 것은 지양 해야 한다. 리액트의 선언적 UI 구성 방식과 잘 어우러지지 않으며 애플리케이션의 복잡성을 높일 수 있음.
함수형 컴포넌트에서의 useRef 우선 사용 : 클래스 컴포넌트에서는 createRef 를, 함수형 컴포넌트에서는 useRef를 사용하는 것이 권장됩니다. 함수형 컴포넌트와 훅을 사용하는 현대 리액트 개발 패러다임에 더 잘 부합합니다.
동적 Ref 사용 시 주의 : 여러 요소에 대한 Ref를 동적으로 생성하고 관리해야 할 때 문자열 대신 함수를 사용하거나 Map 객체를 활용하는 등의 방법으로 관리하는 것이 좋다.
필요한 경우에만 사용 : Ref 는 직접적인 DOM 접근이 필요할 때 사용해야 한다. 포커스 설정, 텍스트 선택 , 미디어 재생제어와 같이
선언적인방식으로 해결할 수 없는 작업에 사용한다.
useRef를 사용하면 DOM에 직접 접근하므로 React의 선언적 흐름을 우회하는 것. 여기서 선언적 이란?? 리액트가 상태와 props를 통해 UI를 자동으로 관리하는 것을 말함
컴포넌트 내부에서만 사용
Ref는 컴포넌트의 구현 세부 사항 을 드러낸다. 이를 외부로 노출하면 컴포넌트가 다른 컴포넌트와 강하게 결합되어 재사용성이 떨어진다는 것
function MyComponent() {
const inputRef = useRef();
// 내부에서 Ref를 사용
const focusInput = () => inputRef.current.focus();
return <input ref={inputRef} />;
}
예를 들면 위 코드에서는 Ref가 컴포넌트 내부에만 존재하므로 외부에서 해당 input 을 제어할 수 없게끔 설계 되어있다. 만약 Ref 를 외부로 노출한다면 외부 컴포넌트(코드) 가 해당 Ref를 남용할 가능성이 있음
상태 업데이트에는 사용하지 않기
Ref 를 통해 상태를 관리하려 하면 React의 렌더링 프로세스 와 동기화 되지 않는 데이터가 발생할 수 있음 즉, 상태 변화가 React의 렌더링 트리거를 동반하지 않으므로 UI가 예상과 다르게 작동할 수 있음.
왜 문자열 Ref는 사용하지 않아야 할까?
React v16 이후, 문자열 Ref는 더 이상 권장되지 않고있다. 이유는 문자열 Ref가 React의 향후 릴리즈에서 제거될 가능성이 있고, 문자열 Ref 는 컴포넌트 사이에서 값을 동적으로 할당하거나 변경하기 어렵기 때문