React Query에서 `queryFn`에서 언랩(unwrapping) 하는 것과 `select` 옵션으로 언랩하는 것의 차이를 정리합니다.
언랩(unwrapping)이란?
"언랩(unwrapping)"은 일반적으로 감싸여 있거나 포장된 데이터를 풀어내어 원하는 실제 값이나 내용을 추출하는 과정을 말한다.
React Query나 API 호출에서 언랩은 보통 API 응답 객체 내 여러 계층 중 실제 필요한 데이터 부분만 꺼내서 사용하는 것을 의미한다.
언랩(unwrapping)의 의미
- 예를 들어, API 응답이 다음과 같이 복잡한 구조일 때:
{
"status": "success",
"data": {
"user": { "id": 1, "name": "Alice" }
},
"message": "OK"
}
- 여기서 실제 화면에 필요한 값은
response.data.user
인데, 언랩은 이런 중첩된 구조에서data.user
부분만 쏙 빼내서 쓰는 행위를 말한다.
React Query에서 언랩 사용 예
- queryFn에서 언랩
queryFn
내부에서 응답에서 필요한 부분만 리턴하는 것→ useQuery는 바로user
객체를 받아서 쓸 수 있음
const fetchUser = async () => {
const res = await fetch('/api/user');
const json = await res.json();
return json.data.user; // 언랩
};
- select 옵션에서 언랩
queryFn
은 전체 응답을 반환하고,select
콜백에서 필요한 부분만 선택하여 반환
const { user } = useQuery('user', fetchUser, {
select: (response) => response.data.user, // 언랩
});
요약
- 언랩은 데이터 구조에서 실제 필요한 값만 꺼내 쓰는 것
- API 응답에서 중첩된 데이터 중 필요한 부분을 "풀어내는" 과정
- React Query에서는
queryFn
이나select
에서 언랩을 할 수 있고, 컴포넌트가 간편하게 데이터를 사용할 수 있도록 돕는다. - ① `queryFn`에서 언랩
`queryFn`이 payload만 반환 → 캐시에 payload만 저장됨. 컴포넌트는 q.data만 보면 끝. (“queryFn이 반환한 값이 캐시에 저장된다”는 것이 기본 규칙 - ② `select`에서 언랩
`queryFn`이 반환한 원본 데이터는 캐시에 그대로 저장되고, select는 구독자에게 넘길 반환값만 변환한다. 즉, 캐시 내용은 변하지 않는다. select는 데이터가 바뀌거나 select 함수 참조가 바뀔 때만 재실행된다.
https://tanstack.com/query/v4/docs/framework/react/reference/useQuery?utm_source=chatgpt.com
useQuery | TanStack Query React Docs
tsx const { data, dataUpdatedAt, error, errorUpdateCount, errorUpdatedAt, failureCount, failureReason, fetchStatus, isError, isFetched, isFetchedAfterMount, isFetching, isInitialLoading, isLoading, is...
tanstack.com
1. queryFn에서 언랩하기 (Axios/DTO 결합 ↓, 메모리 ↓)
`queryFn`은 useQuery에 데이터를 가져오는 비동기 함수(fetcher)를 직접 넘기게 되는데, 여기서 "언랩"이란 fetch/axios 결과의 .json() 또는 .data 같은 실제 원하는 부분을 반환하도록 직접 가공하는 것을 의미한다.
const fetchUser = async () => {
const response = await fetch('/api/user');
// 언랩: response 구조에서 data만 추출하여 반환
return response.json();
};
// useQuery에서 반환 데이터 = 실제 user 데이터
const { data } = useQuery({ queryKey: ['user'], queryFn: fetchUser });
- 장점: 쿼리 내부에서 받는 데이터 형식이 단순해지고, 컴포넌트에서 매번 .data, .json()을 처리할 필요 없음.
- 단점: 여러 컴포넌트에서 다양한 형식의 후처리가 필요하면 그때마다 `fetcher`를 변경해야 함.
2. select 옵션으로 언랩하기 (같은 쿼리를 여러 방식으로 가공해 쓰고 싶을 때 유용)
`select`는 `useQuery`의 옵션으로, 쿼리 함수가 반환한 전체 결과를 받아서 원하는 대로 가공(언랩)하여 컴포넌트에 전달하는 역할이다.
`select`는 반환 값을 변환하지만 캐시에 저장되는 값은 바뀌지 않는다. 데이터/함수 참조가 변할 때만 재실행한다.
const fetchUser = async () => fetch('/api/user').then(res => res.json());
// 서버에서 { user: {...}, status: "ok" }처럼 내려올 경우
const { data } = useQuery({
queryKey: ['user'],
queryFn: fetchUser,
select: (result) => result.user // 언랩: select에서 필요한 값만 추출
});
- 장점: `fetcher`(공통 로직)는 건드리지 않고도, 개별 컴포넌트(혹은 쿼리)마다 원하는 데이터만 뽑아 쓸 수 있음.
- 단점: `select` 로직이 지나치게 복잡해질 수 있고, 데이터가 바뀔 때마다 `select` 구조도 많이 변경될 수 있음.
비교 요약
구분 | queryFn에서 언랩 | select에서 언랩 |
---|---|---|
정의 위치 | fetcher/Fetcher 함수 내부 | useQuery 옵션 (select 콜백) |
변경 영향 범위 | fetcher를 공유하는 모든 곳 | 해당 쿼리(useQuery)만 |
코드 일관성/재사용성 | fetcher가 단순할수록 좋고 일관됨 | 각 쿼리에서 후처리 자유로움 |
대표 장점 | 컴포넌트에서 가공 필요 없어 편리 | 다양한 데이터 구조에 유연 대응 |
대표 단점 | fetcher 함수가 여러 역할을 가짐 | select 중복, 복잡해질 수 있음 |
결론:
- 여러 곳에서 공통 패턴으로 데이터 언랩이 필요하면 `queryFn`에서 언랩이 편함.
- 컴포넌트별로 커스터마이즈된 데이터 언랩이 필요하면 `select` 옵션이 유용하다[2][5][7][8].
참고
[1] [React] React-query 정리 - 박히밍 개발 블로그 - 티스토리 https://heeeming.tistory.com/entry/React-React-query-%EC%A0%95%EB%A6%AC
[2] React Query의 queryFn은 언제 async 함수로 호출되어야 ... https://velog.io/@parkseonup/React-Query%EC%9D%98-queryFn%EC%9D%80-%EC%96%B8%EC%A0%9C-async-%ED%95%A8%EC%88%98%EB%A1%9C-%ED%98%B8%EC%B6%9C%EB%90%98%EC%96%B4%EC%95%BC-%ED%95%A0%EA%B9%8C
[3] [REACT] React Query(TanStack Query) 직접 적용해보며 알아 ... https://s-ryung.tistory.com/70
[4] [개발, 매일메일] @tanstack/react-query v4/v5 차이...(suspense ... https://developer-dreamer.tistory.com/170
[5] React Query/Tanstack Query - ash9river - 티스토리 https://ash9river.tistory.com/34
[6] [WizSched] TanStack Query v5를 적용하여 Google ... https://youngju-js.tistory.com/58
[7] 타입 안전한 React Query 구현하기 https://codingmax.net/courses/ko-react-query/section01/lec0020
[8] TanStack Query(React Query) 핵심 정리 https://www.heropy.dev/p/HZaKIE
[9] [React] 도대체 Tanstack Query가 뭔데 이렇게 많이 써? https://bbjbc.github.io/tanstack-query/react/sixty-seventh-posting/
[10] RTK Query를 이용하여 데이터 최신으로 관리하기(& Redux ... https://cntechsystems.tistory.com/161
'Development > React' 카테고리의 다른 글
[ReactFlow] 이제 reactflow 대신 @xyflow/react (1) | 2025.08.18 |
---|---|
[React] ReactQuery 순환 참조 (1) | 2025.06.09 |
[React] React에서 key 중복으로 발생한 렌더링 이슈 (Reconciliation 사례) (1) | 2025.05.27 |
[React] useId()를 사용하다가 삽질한 기록 (4) | 2025.05.25 |
[TypeScript] 고급 타입 활용법: 조건부 타입, 제네릭 심화와 Exclude/Extract 활용 (0) | 2025.04.01 |