Next.js 15과 TypeScript로 Redux 효율적으로 설정하기
2025-02-26 06:14:04Next.js 15에서 Redux와 TypeScript 통합하기
Next.js 15과 TypeScript를 조합한 최신 웹 애플리케이션 개발 환경에서 Redux를 효과적으로 설정하는 방법을 탐구합니다. Redux 통합은 간단해 보일 수 있지만, 대형 프로젝트에서는 모듈화와 확장성을 유지하는 것이 매우 중요합니다. 그 방법으로 MainProvider를 활용한 방법을 소개하겠습니다.
시작하며
Next.js 15에서는 기존보다 더욱 직관적이고 효율적인 글로벌 상태 관리를 필요로 합니다. 전통적인 방식으로는 Redux Provider를 전체 앱에 직접 바인딩했지만, 이는 종종 전체 코드 유지 보수에 어려움을 주었습니다. 따라서, 별도의 MainProvider 컴포넌트를 도입하여 이 문제를 해결합니다.
단계별 가이드: Redux 설정
1. 루트 레이아웃 설정
RootLayout.tsx는 모든 글로벌 프로바이더를 감싸주는 MainProvider를 포함합니다. 이는 모든 컴포넌트를 깔끔하게 유지하며 확장성을 고려한 구조입니다.
export default function RootLayout({ children }: { children: React.ReactNode }) {
return (
<html lang="en" className="dark" style={{ colorScheme: "dark" }}>
<body className="antialiased w-full min-h-screen overflow-x-hidden">
<MainProvider>{children}</MainProvider>
</body>
</html>
);
}
2. 메인 프로바이더 설정
MainProvider.tsx 파일을 별도로 생성하여 모든 프로바이더(Redux, Auth, Theme 등)를 중앙으로 관리합니다. 현재는 ReduxProvider만을 포함하지만, 필요에 따라 다른 프로바이더를 쉽게 추가할 수 있습니다.
"use client";
import ReduxProvider from "./ReduxProvider";
const MainProvider: React.FC<{ children: React.ReactNode }> = ({ children }) => {
return <ReduxProvider>{children}</ReduxProvider>;
};
export default MainProvider;
3. Redux 프로바이더 설정
ReduxProvider.tsx는 Redux 스토어를 초기화하고 이를 애플리케이션 전체에 제공하는 역할을 합니다. useRef를 사용하여 스토어의 반복 초기화를 방지합니다.
"use client";
import { useRef } from "react";
import { Provider } from "react-redux";
import { store, AppStore } from "@/lib/redux/store";
const ReduxProvider: React.FC<{ children: React.ReactNode }> = ({ children }) => {
const storeRef = useRef<AppStore | null>(null);
if (!storeRef.current) {
storeRef.current = store();
}
return <Provider store={storeRef.current}>{children}</Provider>;
};
export default ReduxProvider;
4. Redux 스토어 설정
Redux의 store.ts 파일을 설정하여 Redux의 상태 관리를 위한 환경을 만듭니다. 이는 다양한 서버측 작업 및 미들웨어 통합을 고려한 구조입니다.
import { configureStore } from "@reduxjs/toolkit";
import favoriteReducer from "./features/favorite/favoriteSlice";
export const store = () => {
return configureStore({
reducer: {
favorite: favoriteReducer,
},
});
};
export type AppStore = ReturnType<typeof store>;
export type RootState = ReturnType<AppStore["getState"]>;
export type AppDispatch = AppStore["dispatch"];
5. Redux를 위한 타입 지정 훅 생성
Typed Redux 훅을 활용하여 useDispatch와 useSelector를 직접 가져다 쓰지 않고 이러한 작업의 타입을 정의합니다.
import { useDispatch, useSelector, useStore } from "react-redux";
import type { RootState, AppDispatch, AppStore } from "@/lib/redux/store";
export const useAppDispatch = useDispatch.withTypes<AppDispatch>();
export const useAppSelector = useSelector.withTypes<RootState>();
export const useAppStore = useStore.withTypes<AppStore>();
6. Redux Slice 생성
features/favorite/favoriteSlice.ts에서 즐겨찾기 아이템을 관리할 슬라이스를 생성합니다. 이는 모듈화된 상태 관리를 지원하며, 다양한 기능 추가를 쉽게 만듭니다.
import { createSlice, nanoid, type PayloadAction } from "@reduxjs/toolkit";
import { useAppSelector } from "@/hooks/redux.hooks";
interface FavoriteProductType {}
interface InitialStateType {
favoriteProduct: FavoriteProductType[];
}
const initialState: InitialStateType = {};
const favoriteSlice = createSlice({
name: "favorites",
initialState,
reducers: {
addFavorite: (state, action: PayloadAction<FavoriteProductType>) => {},
},
});
export const useFavoriteProduct = () =>
useAppSelector((state) => state.favorite);
export const { addFavorite } = favoriteSlice.actions;
export default favoriteSlice.reducer;
결론
이처럼 구조화된 접근 방식을 통해 Redux를 Next.js 15에 통합함으로써 클린하고 확장 가능한 아키텍처를 유지할 수 있습니다. 이러한 설정은 향후 프로젝트 확장 및 유지보수에 중요한 기반이 됩니다.
참고하면 도움 될만한 URL: