안녕하세요 OB 김건휘입니다🌊. 이번 시간에는 useRef 훅을 딥다이브 해보는 시간을 가져보도록 하겠습니다.
📌useRef
렌더링과는 별개로 변수를 사용하거나 DOM 요소에 접근할 때 사용되는 기능이다.
useState의 경우 값을 바꿀 때 화면도 렌더링 되지만, useRef는 렌더링과 관계없이 변경 가능한 값들을 가질 수 있다.
=> Ref는 State와 비슷하게 어떠한 값을 저장해두는 저장 공간으로 활용됨
📌useRef vs useState
특성 | useRef | useState |
리렌더링 여부 | 값이 변경되어도 리렌더링되지 않음 | 값이 변경되면 리렌더링 발생 |
용도 | DOM 참조, 이전 값 저장, 비상태 값 관리 | 상태 값을 저장하고 UI 갱신 |
초기화 시점 | 컴포넌트 초기화 시 1회 설정 | 값 변경 시마다 갱신 가능 |
📌 예시코드
import { useState, useRef } from 'react';
function App() {
const [count, setCount] = useState(0);
const countRef = useRef(0);
console.log(countRef);
console.log('랜더링');
const handleCountUpdate = () => {
setCount(count + 1);
};
const handleCountRef = () => {
countRef.current = countRef.current + 1;
};
return (
<div>
<p>State: {count}</p>
<p>Ref: {countRef.current}</p>
<button onClick={handleCountUpdate}>State 올려</button>
<button onClick={handleCountRef}>Ref 올려</button>
</div>
);
}
export default App;
Ref 올려 버튼 클릭 시:
- 화면상의 변화는 생기지 않는다.
- 그러나 State 올려 버튼 클릭시 랜더링이 발생하여 Ref 올려 버튼을 클릭했던 횟수만큼 카운트 되어 화면에 등장하는 것을 확인할 수 있다.
랜더링이 발생하면 변수는 초기화 되지만 Ref는 초기화 되지 않음. 아래 영상 참고.
🧐useRef는 어떤 상황에서 활용하면 좋을까?
1. DOM 요소에 접근
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 요소에 직접 접근할 수 있기 때문이다. 이는 리액트에서 DOM 조작을 필요로 하는 다양한 상황에서 활용될 수 있다.
2. 값 저장 (리렌더링 없이 상태 유지)
useRef를 사용하면 값이 변경되어도 컴포넌트가 리렌더링되지 않는다. 렌더링 간 데이터를 유지하거나, 이전 상태 값을 추적할 때 유용하게 사용 가능. 즉, 변경 시 렌더링을 발생시키지 않아야 하는 값을 다룰 때 주로 useRef를 사용한다.
📌Ref 활용의 모범 사례와 주의 사항
리액트에서 Ref는 매우 강력한 기능을 제공하지만 이를 사용할 때는 주의가 필요하다. 올바르게 사용되지 않으면 애플리케이션의 성능 저하나 예측 불가능한 버그를 초래할 수 있기 때문이다.
모범 사례
- 필요한 경우에만 사용: Ref는 직접적인 DOM 접근이 필요할 때 사용해야 합니다. 예를 들어서 포커스 설정, 텍스트 선택, 미디어 재생 제어와 같이 선언적인 방식으로 해결할 수 없는 작업에 사용하세요.
- 컴포넌트 내부에서만 사용: Ref는 컴포넌트 내부에서만 사용하고 외부로 노출시키지 마세요. 컴포넌트의 내부 구현을 외부로 유출시키면 컴포넌트의 재사용성과 유지 보수성이 떨어집니다.
- 상태 업데이트에는 사용하지 않기: Ref를 사용해 상태 업데이트와 같은 리액트의 데이터 흐름을 우회하는 것은 피해야 합니다. 상태 관리는 useState나 useReducer와 같은 상태 관리 훅을 사용하세요.
주의 사항
- Ref 남용 방지: 모든 상호 작용이나 DOM 조작에 Ref를 사용하는 것은 피해야 합니다. 리액트의 선언적 UI 구성 방식과 잘 어우러지지 않으며 애플리케이션의 복잡성을 높일 수 있습니다.
- 함수형 컴포넌트에서의 useRef 우선 사용: 클래스 컴포넌트에서는 createRef를 함수형 컴포넌트에서는 useRef를 사용하는 것이 권장됩니다. 함수형 컴포넌트와 훅을 사용하는 현대 리액트 개발 패러다임에 더 잘 부합합니다.
- 동적 Ref 사용 시 주의: 여러 요소에 대한 Ref를 동적으로 생성하고 관리해야 할 때 문자열 대신 함수를 사용하거나 Map 객체를 활용하는 등의 방법으로 관리하는 것이 좋습니다.
최적의 활용 전략
- Ref와 상태의 적절한 조합: 때로는 Ref와 리액트의 상태를 조합해 사용하는 것이 효과적일 수 있습니다. 예를 들어서 입력 필드에 포커스가 있는지 여부를 상태로 관리하면서 실제 포커스 조작은 Ref를 통해 수행하는 식입니다.
- 커스텀 훅을 통한 추상화: 공통적으로 사용되는 DOM 조작 로직이 있다면 이를 커스텀 훅으로 추상화해 재사용성을 높이세요. 이 방법을 통해 코드의 가독성과 유지 보수성을 향상시킬 수 있습니다.
- 코드 리뷰와 테스트: Ref를 사용한 코드는 특히 주의 깊게 리뷰하고 테스트해야 합니다. 코드 리뷰를 통해 불필요한 Ref 사용을 줄이고 적절한 테스트를 통해 예상치 못한 사이드 이펙트가 없는지 확인하세요.
Ref는 리액트 애플리케이션에서 강력한 기능을 제공하지만 그 사용법을 잘 이해하고 신중하게 활용해야 한다. 모범 사례를 따르고 주의 사항을 유의하여 깔끔하고 유지 보수가 용이한 코드를 작성하는 것이 중요하다.
🧐궁금한점
const inputRef = useRef(null); <input ref={inputRef} /> 이렇게 사용하면 input태그에 접근할 수 있는데 정확히 어떤 원리로 접근 가능한건지 궁금하다.
'나야, 리액트 스터디' 카테고리의 다른 글
[Week 6] Ref (1) | 2024.12.02 |
---|---|
[week6]탈출구 - Ref로 값 참조하기, Ref로 DOM조작하기 (2) | 2024.12.01 |
[week6] Ref (1) | 2024.12.01 |
[week 6] Ref로 값 참조하기, Ref로 DOM조작하기 (3) | 2024.12.01 |
[week6] Ref로 값 참조하기 (3) | 2024.12.01 |