728x90
시작하며
React 프로젝트를 하다 보면 특정 동작을 오직 한 번만 실행하거나, 중복 호출을 막아야 하는 상황이 자주 발생합니다. 특히, API 호출이 불필요하게 여러 번 호출될 경우에는 성능에 영향을 줄 뿐만 아니라 더 나아가 데이터베이스 무결성에 영향을 줄 가능성이 있습니다.
오늘은 useEffect를 활용하여 앞선 문제를 간단하고 효율적으로 해결하는 방법을 소개하고자 합니다.
왜 useEffect를 사용할까?
React에서 상태 관리를 위한 useState와 달리 useRef는 값이 변경되어도 렌더링에 영향을 주지 않으며 값이 동기적으로 즉시 변경된다는 특징을 가지고 있습니다.
useRef의 주요 특징
1. 렌더링과 독립적
- ref 값이 변경되어도 컴포넌트가 리렌더링되지 않습니다.
- 불필요한 렌더링을 방지하여 성능 최적화가 가능합니다.
2. 동기적 업데이트
- ref.current 값을 즉시 변경하고 바로 사용이 가능합니다.
- setState처럼 비동기적 처리 과정을 기다릴 필요가 없습니다.
3. 심플한 구현
- 코드가 직관적이며 복잡한 로직이 필요 없이 원하는 동작을 구현할 수 있습니다.
코드 예시: API 중복 호출 방지
✅ useRef로 구현한 중복 호출 방지
import { useRef } from "react";
function ExampleComponent() {
const isFetching = useRef(false); // API 호출 여부를 추적하는 플래그
const fetchData = async () => {
if (isFetching.current) return; // 중복 호출 방지
isFetching.current = true; // 플래그 설정
try {
const response = await fetch("https://api.example.com/data");
console.log("Fetched data:", await response.json());
} catch (error) {
console.error("Error fetching data:", error);
} finally {
isFetching.current = false; // 호출 완료 후 플래그 초기화
}
};
return <button onClick={fetchData}>Fetch Data</button>;
}
🔍 작동 원리
- isFetching.current 플래그가 true인 동안 API 호출을 차단합니다.
- API 요청이 완료되면 다시 false로 초기화하여 새로운 요청 허용합니다.
- 이 과정이 동기적으로 실행되므로 불필요한 렌더링 없이 작동합니다.
❌ useState를 사용한 비효율적 구현
import { useState } from "react";
function ExampleComponent() {
const [isFetching, setIsFetching] = useState(false);
const fetchData = async () => {
if (isFetching) return; // 중복 호출 방지
setIsFetching(true); // 상태 설정
try {
const response = await fetch("https://api.example.com/data");
console.log("Fetched data:", await response.json());
} catch (error) {
console.error("Error fetching data:", error);
} finally {
setIsFetching(false); // 상태 초기화
}
};
return <button onClick={fetchData}>Fetch Data</button>;
}
🔍 문제점
- setState는 비동기적으로 동작하기 때문에 isFetching 값이 즉시 업데이트되지 않을 수 있습니다.
- 이로 인해 중복 호출 방지 로직이 동작하지 않을 가능성이 있습니다.
마무리하며
그렇다면 언제 useRef를 사용하는 것이 적합할까요? 특정 로직이 렌더링과 상관 없이 독립적으로 작동할때, 동기적인 값 관리가 중요한 경우(API 호출 방지, 이벤트 제어 등)가 있을 것으로 보입니다.
useRef를 적절히 활용하면 React의 선언적 렌더링 흐름("무엇을 렌더링할지"에만 집중하는 방식)을 챙기는 것에도 큰 도움이 될 수 있습니다.
728x90
'Web > React' 카테고리의 다른 글
[React] Warning: React has detected a change in the order of Hooks 에러 해결하기 (0) | 2024.07.17 |
---|---|
[React] 접근 제한을 위한 Private Route 만들기 (0) | 2024.04.21 |
[React] Invalid Hook Call Warning 해결하기 (0) | 2024.04.15 |
[Recoil] React를 위한 상태 관리 라이브러리, Recoil에 대하여 알아보자 (2) | 2024.02.07 |
[React + Vite] "Failed to load resource: the server responded with a status of 404(not found)" 해결하기 (0) | 2023.11.16 |