posts

RTK Query React Hooks 랜더링 이슈

Apr 23, 2026 updated Apr 23, 2026 apireactrenderingrtk-query

이 문서는 RTK Query에서 생성해서 제공해주는 React Hooks(use...Query, user..,Mutation)를 사용하는 과정에 반복적으로 발생하는 랜더링 이슈를 파악하고

그에 대한 대응 방법을 정리한 문서입니다.

아래서 나오는 코드들은 rtk skeleton repo를 기준으로 작성되었습니다

link →https://git.hnine.com/HNINE-Ex/rtk-skeleton

rtk query link →https://redux-toolkit.js.org/rtk-query/usage/queries

RTK Query에서 제공해주는 React Hooks 사용 방법은 일반적으로 다음과 같습니다.

//둘다 profile 정보를 가져오는 fetch를 수행합니다. //query, mutation 의 차이는 RTK Query docs를 확인해주세요 const [getProfile, { isSuccess: profileIsSuccess, isError}] = useGetProfileMutation(); const { data, isLoading, isFetching, isSuccess} = useGetProfileWithIdQuery(2);

위처럼컴포넌트 내부에서 사용하면 내부스토어에서관리되는 상태에 따라 data, 및isLoading등이 변경되어 상태가변경될 때마다컴포넌트가 렌더됩니다.

여기서 발생하는 문제가 구조분해로 가져오지 않은 스테이트가변경되었을 때도컴포넌트가 렌더된다는것입니다.

//이해를 돕기위해 뮤테이션를 사용하여 설명 하겠습니다 ( 내부적으로 동작은 쿼리와 뮤테이션 둘다 비슷합니다) const Test = () => { const [getProfile, { isSuccess, isError }] = useGetProfileMutation(); // (1) //const [getProfile] = useGetProfileMutation(); (2) useEffect(()=> { getProfile(2); }, []); return(

{console.log("Test Render!!"}
) }

처음 hooks를 사용할때 기대한 것은 hooks가 돌려주는 data, isLoading 같은 스테이트를 사용자가 구조분해로 꺼내온 것들만이 렌더에 영향을 줄것으로 생각했습니다.

(실제 swr 은 그렇게 동작한다고 합니다 link →https://swr.vercel.app/ko/docs/advanced/performance#%EC%9D%98%EC%A1%B4%EC%84%B1-%EC%88%98%EC%A7%91)

하지만 구조분해를 어떻게 하는지는 렌더에 영향을 주지 않았습니다 위 코드의 (1), (2) 두 방식 모두 다음과 같은 결과를 보여줍니다.

RTK Query React Hooks 랜더링 이슈 이미지 1

로그를 살펴보면 'Test Render!!' 가 두번찍힌걸로 봐서 렌더가 두번 된것을 확인할수 있습니다.

rtk query는 각 api마다 store내부에서 데이터를 관리하는데 그부분을 살펴보겠습니다.

각 api 요청에 따라 rtk query가 정의해놓은 fetch에 대한 정해진 파이프라인 액션들이 실행되고 그에따라 rtk query에서 관리하는 state들이 변경됩니다

fetch 요청이 시작되면 /pending 액션 이후 요청이 성공하면 /fulfilled 액션이 발행됩니다. (실패하면 /rejected 액션이 발행됩니다)

redux devtools 로 액션을 확인하면

RTK Query React Hooks 랜더링 이슈 이미지 2

RTK Query React Hooks 랜더링 이슈 이미지 3

state 가 변경되고 값들의 변화에 따라 컴포넌트에서 구독하고 있는 hooks 들이 렌더를 발생시킵니다.

여기서 hooks를 사용하는 컴포넌트들이 어떻게 다시 렌더 되는지 알기 위해서는 rtk query가 hooks를 생성할때 내부에서 selector를 어떻게 관리하는지 알아봐야합니다.

먼저 query 및 mutation hooks가 어떻게 만들어지는지 확인해 보겠습니다.

link →https://github.com/rtk-incubator/rtk-query/blob/4972751be85462c5f733cfac0960d5a25138b54f/src/react-hooks/module.ts#L104

RTK Query React Hooks 랜더링 이슈 이미지 4

위 코드는 createApi를 통해 endpoint 들을 등록하면 자동으로 hooks를 생성하는 코드의 일부입니다. (위 링크를 통해 전체코드를 확인하세요)

쿼리 인지 뮤테이션 인지를 파악하여 buildQueryHooks, buildMutationHook 함수를 통해 hooks 들을 생성합니다.

query 를 기준으로 설명하면 공식 docs 에서는 query hooks 에 대해 이렇게 설명하고 있습니다.

RTK Query React Hooks 랜더링 이슈 이미지 5

우리가 컴포넌트에서 사용하는 use...Query 는

RTK Query React Hooks 랜더링 이슈 이미지 6

위 코드처럼 useQuery를 사용합니다. 그리고 useQuery 는 두가지를 구성한다고 되어있습니다.

useQuerySubscription → refetch 함수를 반환하고 컴포넌트의 store에 대한 구독을 담당합니다.

useQueryState → 쿼리 state 를 반환하고 데이터를 반환 합니다.

link →https://github.com/rtk-incubator/rtk-query/blob/4972751be85462c5f733cfac0960d5a25138b54f/src/react-hooks/buildHooks.ts#L360

buildQueryHooks 함수의 리턴값을 살펴보면 useQuery 가 useQuerySubscription, useQueryState 두 결과를 묶어서 리턴하는것을 볼 수 있습니다.

RTK Query React Hooks 랜더링 이슈 이미지 7

여기서 우리가 확인해야할 부분은 데이터를 관리하는 useQueryState 함수입니다. 코드를 살펴보면

link →https://github.com/rtk-incubator/rtk-query/blob/4972751be85462c5f733cfac0960d5a25138b54f/src/react-hooks/buildHooks.ts#L486

RTK Query React Hooks 랜더링 이슈 이미지 8

useQueryState 함수는 컴포넌트에서 전달된 arg 및 skip , selectFromResult 를 통해 selector 를 생성하고

해당 selector를 통해 구독하고 있는 state 데이터의 변화를 감지하여 렌더링을 발생시킵니다.

이때 컴포넌트에서 selectFromResult 가 전달되지 않으면 defaultQueryStateSelector 를 기본으로 사용하는데

defaultQueryStateSelector 를 살펴보면

link →https://github.com/rtk-incubator/rtk-query/blob/4972751be85462c5f733cfac0960d5a25138b54f/src/react-hooks/buildHooks.ts#L287

RTK Query React Hooks 랜더링 이슈 이미지 9

우리가 컴포넌트에서 구조분해를 통해 가져올 수 있었던 data, isFetching 등을 묶어서 리턴하는것을 볼 수 있습니다.

따라서 .... 컴포넌트에서 쿼리의 옵션으로 selectFromResult 를 전달하지 않으면 defaultQueryStateSelector 를

selectFromResult 로 사용하게되고 구조분해와 관련없이 저 데이터중 하나라도 변하면 다시 리렌더가 됩니다.

(mutation 도 비슷합니다 위에 코드를 보면 currentState 전체를 리턴하는것을 볼 수 있습니다.)

이 리렌더 문제를 해결하기 위해서는 컴포넌트에서 사용할때

RTK Query React Hooks 랜더링 이슈 이미지 10

위와 같이 selectFromResult정의 할 때 렌더에 영향을 줄 state 만 선택하여 옵션으로 전달할 수 있습니다.

RTK Query React Hooks 랜더링 이슈 이미지 11

그 결과로 isError state의 값이 변경될때만 리렌더 됩니다.

selectFromResult 를 통해서 필요한 값만 구독하는 형태로 동작하기때문에 공식 도큐먼트에서 나오는 문서를 보면

link →https://redux-toolkit.js.org/rtk-query/usage/queries#selecting-data-from-a-query-result

RTK Query React Hooks 랜더링 이슈 이미지 12

포스트 리스트중에 특정 아이디를 지닌 포스트의 값을 구독하는 형태로 리렌더를 제어할수 있습니다.

예를들어 포스트 1,2,3 이 있을때 내가 2번 포스트를 값을 구독하고 있다면 1번 혹은 3번의 값이 바뀌더라도

해당 컴포넌트는 리렌더가 되지않습니다.

정리

만들어진 query, mutation 에 대한 훅을 그냥 쓰게되면 default로 지정된 selectFromResult 함수를 통해

state 들의 값이 바뀔때마다 리렌더 될 것이고 selectFromResult를 새로 정의하여 렌더링을 일으킬 state를 지정할 수 있습니다.