[Redux Toolkit] baseUrl 동적으로 생성하기

aborile·2023년 10월 30일
0

React / Next

목록 보기
4/4
post-thumbnail

기존에는 serverURL을 전역에서 사용할 수 있는 공통 상수로 만들어 두고 이를 import하는 식으로 baseQuery에서 baseUrl을 지정하여 사용하고 있었다.

const serverURL = "https://...";

export const authApi = createApi({
  reducerPath: "auth",
  baseQuery: fetchBaseQuery({
    baseUrl: `${serverURL}/v1/auth`,
  }),
  endpoints: (builder) => ({
    // ...
  }),
});

하지만 특정 state를 기준으로 동적으로 server url을 변경해야 하는 요구사항이 생겼다. 어떻게 구현해야 좋을지 고민하며 이런 저런 방법을 찾아보던 중, 해당 state를 redux state로 저장한 뒤, baseQuery를 함수 꼴로 사용하여 이를 읽어오는 방식으로 구현하기로 결정하였다.

대강의 구현 방식은 다음과 같다. baseQuery를 함수 꼴로 사용하면 두번째 인자를 통해 현재 redux state를 읽어올 수 있게 된다. redux state 내에 server url을 관리하는 serverUrl이라는 상태가 있다고 가정하면,

export const authApi = createApi({
  reducerPath: "auth",
  baseQuery: (args, baseQueryApi, options) => {
    const baseUrl = (baseQueryApi.getState() as CustomReduxState).serverUrl;
    return fetchBaseQuery({ baseUrl: `${baseUrl}/v1/auth` })(args, baseQueryApi, options);
  },
  endpoints: (builder) => ({
    // ...
  }),
});

이런 식으로 불러올 수 있게 되는 것이다. return value로 기존의 fetchBaseQuery를 호출한 뒤 인자를 전부 넘겨주면 끝이다. 이를 조금 더 고도화 해 보자.

baseQuery를 함수 꼴로 사용하기 위한 함수를 dynamicBaseQuery라는 별도의 함수로 분리하고, 이를 baseUrlPath를 구체적으로 명시하는 것까지 공통함수화 하는 고차 함수로 작성하였다. 전체 코드는 다음과 같다.

import { BaseQueryFn, FetchArgs, FetchBaseQueryError, fetchBaseQuery } from "@reduxjs/toolkit/query/react";

/**
 * redux toolkit slice의 base query를 동적으로 생성하는 함수. redux state 내 `baseUrl`에 따라 서버 URL이 변경됨.
 * @param baseUrlSuffix 공통으로 `baseUrl`에 넣을 path
 */
export function dynamicBaseQuery(baseUrlSuffix: string): BaseQueryFn<string | FetchArgs, unknown, FetchBaseQueryError> {
  return (args, baseQueryApi, extraOptions) => {
    const serverUrl = (baseQueryApi.getState() as ReduxState).serverUrl;
    const baseUrl = serverUrl.concat(baseUrlSuffix.startsWith("/") ? "" : "/").concat(baseUrlSuffix);
    const rawBaseQuery = fetchBaseQuery({ baseUrl });
    return rawBaseQuery(args, baseQueryApi, extraOptions);
  };
}

export const authApi = createApi({
  reducerPath: "auth",
  baseQuery: dynamicBaseQuery("/v1/auth"),
  endpoints: (builder) => ({
    // ...
  }),
});

dynamicBaseQuerybaseUrlSuffix를 넘겨주어 기존 baseUrl state 뒤에 붙는 세부 path를 입력할 수 있다. 이 함수를 import하여 baseQuery를 동적으로 생성하는 slice를 여러 개 만들 수 있다.

References

https://stackoverflow.com/questions/69568818/how-to-dynamically-change-base-url-using-redux-toolkit

profile
기록하고 싶은 것을 기록하는 저장소

0개의 댓글