"리액트 엔진을 사용하느냐 아니냐"
1. util 폴더: "리액트 따위(?) 몰라도 돼" (Pure JS)
util 폴더에 들어가는 함수들은 리액트라는 환경에 전혀 의존하지 않는 '순수 자바스크립트/타입스크립트' 로직입니다.
- 특징: 어떤 환경(Node.js, 바닐라 JS, React)에서도 그대로 가져다 쓸 수 있습니다.
- 예시: 날짜 포맷팅(2024-05-20 → 2024년 5월 20일), 숫자 세 자릿수 콤마 찍기, 복잡한 수학 계산 등.
- 테스트: 리액트 컴포넌트를 렌더링할 필요 없이 함수만 불러와서 테스트하면 되니 매우 빠르고 쉽습니다.
// 이건 순수 JS 로직이므로 util 폴더에 어울립니다.
export const convertToUpper = (str: string) => str.toUpperCase();
2. hook 폴더: "난 리액트 없으면 못 살아" (React-Dependent)
hook 폴더에 들어가는 함수들은 리액트의 심장 박동(Lifecycle)과 상태 관리 시스템에 연결된 로직입니다.
- 특징: 내부에서 useState, useEffect, useContext 혹은 useQuery(TanStack Query) 같은 리액트 전용 기능을 하나라도 사용합니다.
- 예시: useAuth(로그인 상태 체크), useGetReport(API 데이터 가져오기), useWindowSize(화면 크기 감지).
- 테스트: 반드시 리액트 환경을 꾸며주는 도구(@testing-library/react-hooks 등)가 있어야 테스트가 가능합니다.
// src/hooks/useUpperTitle.ts
import { useEffect, useState } from 'react';
import { convertToUpper } from '@/utils/stringUtils'; // util 사용
export const useUpperTitle = (title: string) => {
const [upper, setUpper] = useState('');
useEffect(() => {
// 리액트의 생명주기(useEffect) 안에서 문자열 처리를 수행
const result = convertToUpper(title);
setUpper(result);
}, [title]); // title이 바뀔 때만 리액트가 알아서 실행해줘!
return upper;
};
API를 호출할 때:
- 단순히 axios.get(...)만 하고 끝나는 순수 통신 로직이라면? → api/ 또는 util/
- useQuery나 useEffect를 써서 그 결과를 리액트 상태나 캐시에 담는 로직이라면? → hook/
이전 글이랑 이어지는 상황 :
api에서 util은 되고 hook은 안된다.
- util -> api (환상의 짝꿍): api 폴더에서 데이터를 받아온 뒤, 그 데이터를 가공하기 위해 util에 있는 문자열 처리 함수를 쓰는 것은 매우 자연스러운 흐름입니다. 둘 다 리액트 엔진 없이도 돌아가는 '자유로운 영혼'들이기 때문이죠.
- hook -> api (금기된 조합): 앞서 공부했듯이, hook은 실행되는 순간 "나 지금 리액트 컴포넌트 안에서 실행 중인가?"를 체크합니다. api 폴더의 일반 함수는 리액트 컴포넌트가 아니므로, 여기서 훅을 부르는 순간 리액트가 "경찰(Error)"을 부릅니다.
'개발' 카테고리의 다른 글
| 프론트엔드 프로젝트 첫 시작 시, 고려사항들 노트용 (0) | 2026.02.09 |
|---|---|
| Complex 컴포넌트 & Headless Hook 아키텍처 정리본 (Table.jsx) (0) | 2026.01.21 |
| 리액트가 훅을 구분한다? (0) | 2026.01.21 |
| Tanstack Query 관리 구조 (공통 훅 정의) (0) | 2026.01.21 |
| Next.js 정리 — React를 쓰다 보면 반드시 헷갈리는 그 지점들 (0) | 2026.01.20 |