훅에서 **useRef**와 **useEffect**는 각각 다른 목적을 가지고 있으며, 렌더링과 관련없는 값을 처리하는 방식도 다릅니다. 이를 이해하기 위해, 두 훅의 주요 차이점과 각각의 역할을 구체적으로 설명하겠습니다.
1. useRef와 useEffect의 차이점
• **useRef**는 주로 DOM 요소에 직접 접근하거나 렌더링과 상관없는 값을 저장하는 데 사용됩니다.
• **useEffect**는 **사이드 이펙트(side effects)**를 처리하는 훅으로, 주로 데이터를 가져오거나(예: API 호출), 타이머 설정 또는 구독(subscription) 설정 등, 컴포넌트가 렌더링된 후에 수행해야 하는 작업을 정의하는 데 사용됩니다.
2. useRef의 목적
• DOM 접근: useRef는 컴포넌트 내부에서 특정 DOM 요소에 직접 접근하고 조작하기 위해 사용됩니다. 예를 들어, 특정 입력 필드에 포커스를 설정하거나, 스크롤 위치를 조정하는 작업을 할 때 유용합니다.
• 값 저장: useRef는 렌더링과 관련 없는 값을 저장하는 데도 사용됩니다. 예를 들어, 컴포넌트가 리렌더링되더라도 값이 유지되어야 하는 경우 useRef로 값을 저장할 수 있습니다. 하지만 useRef의 값을 변경해도 컴포넌트는 리렌더링되지 않습니다.
useRef를 사용할 때:
• DOM 조작: 특정 DOM 요소에 접근해야 할 때 (.focus(), .scrollIntoView() 등).
• 렌더링과 무관한 값을 유지하고 싶을 때 (예: 이전 상태 값 추적, 렌더링 횟수 추적).
3. useEffect의 목적
• 사이드 이펙트 처리: useEffect는 DOM이 렌더링된 이후에 사이드 이펙트를 처리합니다. 즉, API에서 데이터를 가져오거나, 이벤트 리스너를 등록하고, 타이머를 설정하는 등의 작업을 처리합니다. 또한, 의존성 배열을 통해 특정 값이 변경될 때마다 useEffect가 다시 실행됩니다.
• 데이터 초기화 또는 업데이트: 컴포넌트가 처음 렌더링되거나 특정 상태나 props가 변경될 때 비동기 작업을 수행하는 데 주로 사용됩니다. 예를 들어, API 호출이나 구독을 설정하고, 컴포넌트가 언마운트될 때 정리(clean-up) 작업을 할 수 있습니다.
useEffect를 사용할 때:
• 비동기 작업 (예: API 호출).
• 구독(subscription) 설정, 타이머 설정.
• 컴포넌트가 렌더링된 후나 상태/props가 변경될 때 발생하는 작업 처리.
• 컴포넌트가 언마운트될 때 정리 작업 수행.
4. useRef와 useEffect의 차이
특징 | userRef | useEffect |
주요 목적 | DOM 접근 및 렌더링과 무관한 값 저장 | 사이드 이펙트 처리(API 호출, 구독, 타이머 등) |
렌더링 영향 | current 값이 변경되어도 리렌더링되지 않음 | 의존성 배열에 따라 특정 값이 변경되면 다시 실행 |
타이밍 | 컴포넌트가 처음 렌더링되기 전에 DOM요소를 참조 가능 | 컴포넌트가 렌더링된 후에 실행 |
주 용도 | 특정 DOM 요소에 직접 접근하거나 값 저장 | 컴포넌트 렌더링 후 비동기 작업 처리 또는 정리 작업 수행 |
상태 변경과의 관계 | 상태와 관계없이 값 유지 | 상태 또는 props의 변경에 반응하여 다시 실행 |
정리 작업 | 정리 작업 없음 | return을 통해 정리 작업을 처리할 수 있음 |
5. 예시로 이해하기
useRef로 DOM 조작 (입력 필드에 포커스 설정)
import React, { useRef } from 'react';
function FocusInput() {
const inputRef = useRef(null);
const handleClick = () => {
inputRef.current.focus(); // 버튼을 클릭하면 input 필드에 포커스
};
return (
<div>
<input ref={inputRef} type="text" placeholder="Click the button to focus" />
<button onClick={handleClick}>Focus the input</button>
</div>
);
}
• useRef는 DOM 요소에 직접 접근하여 포커스를 설정합니다. 이 작업은 렌더링과는 상관없이 DOM 조작이 필요할 때 사용됩니다.
useEffect로 API 호출 및 데이터 설정
import React, { useState, useEffect } from 'react';
function FetchDataComponent() {
const [data, setData] = useState(null);
useEffect(() => {
// 컴포넌트가 렌더링된 후 API 호출
fetch('https://api.example.com/data')
.then((response) => response.json())
.then((result) => setData(result));
// 정리 작업: 컴포넌트 언마운트 시 호출
return () => {
console.log('Component unmounted, cleanup...');
};
}, []); // 빈 배열이므로 한 번만 실행
return <div>Data: {JSON.stringify(data)}</div>;
}
• useEffect는 컴포넌트가 렌더링된 후 API를 호출하고 데이터를 설정하는 역할을 합니다.
• useEffect는 DOM 조작보다는 비동기 작업이나 컴포넌트의 생명주기에 맞춰 작업을 처리하는 데 사용됩니다.
6. useRef와 useEffect의 사용 시점 요약
• useRef를 사용할 때:
• 특정 DOM 요소에 직접 접근해야 할 때 (예: focus, scroll).
• 렌더링과 관계없는 값을 저장하고 유지해야 할 때 (예: 이전 상태 추적, 렌더링 횟수 추적).
• useEffect를 사용할 때:
• 렌더링 후 실행되어야 하는 작업이 있을 때 (예: API 호출, 데이터 가져오기).
• 상태나 props가 변경될 때마다 특정 작업을 다시 실행해야 할 때.
• 컴포넌트가 언마운트될 때 정리 작업을 수행해야 할 때.
7. 결론
• **useRef**는 DOM 접근과 렌더링과 관련 없는 값의 저장에 사용되며, 값이 변경되어도 리렌더링되지 않습니다. 주로 특정 DOM 요소에 직접적인 명령을 내릴 때 유용합니다.
• **useEffect**는 사이드 이펙트를 처리하는 훅으로, 컴포넌트가 렌더링된 후에 실행됩니다. API 호출, 데이터 가져오기, 타이머 설정 등의 비동기 작업을 처리하고, 의존성 배열을 통해 특정 상태가 변경될 때마다 실행될 수 있습니다.
두 훅은 목적과 사용 시점이 다르므로, 각각의 상황에 맞게 적절하게 사용하는 것이 중요합니다.
'React' 카테고리의 다른 글
[React] 직접적인 Dom조작은 피해라 (1) | 2024.09.15 |
---|---|
[React] 커스텀 훅 만들기 (2) | 2024.09.15 |
[React] useRef 훅 사용법 (1) | 2024.09.13 |
[React] useEffect 훅, 의존성 배열 (0) | 2024.09.13 |
[React] Hooks (0) | 2024.09.13 |