-
NextJS + Redux-Toolkit + next-redux-wrapper 설정하기Next.js 2021. 9. 24. 18:33728x90
해당 글은 next-redux-wrapper@7 버전을 기반으로 작성되었습니다.
해당 방법은 필자 개인이 설정한 방법으로 언제든 더 좋은 방법이 있다면 공유해주시기 바랍니다.
NextJS의 큰 장점 중 하나인 SSR을 사용할 때 조금 더 편하게 사용하기 위해 next-redux-wrapper를 이용하여 dispatch를 사용할 수 있게 된다.
// testReducer.ts export const initialState = { // ...states } export type TestReducerState = typeof initialState; const testSlice = createSlice({ name: 'user', initialState, reducers: {}, extraReducers: (builder) => // anyExtraReducers... }); export default testSlice;
위와 같은 reduser를 test1, test2로 만들었다고 가정하고 진행하려고 한다.
toolkit의 사용법의 경우 다음에 다뤄보도록 하겠다.
// reducer.ts import { AnyAction, CombinedState, combineReducers } from 'redux'; import { HYDRATE } from 'next-redux-wrapper'; import test1Slice, { Test1ReducerState } from './test1'; import test2Slice, { Test2ReducerState } from './test2'; export interface IState { test1: Test1ReducerState; test2: Test2ReducerState; } const rootReducer = (state: IState, action: AnyAction): CombinedState<IState> => { switch (action.type) { case HYDRATE: return action.payload; default: { const combinedReducer = combineReducers({ user: userSlice.reducer, post: postSlice.reducer, }); return combinedReducer(state, action); } } }; export default rootReducer;
위와 같이 만들어 놓은 reducer들을 합치는 것은 동일하지만 HYDRATE를 이용하여 SSR상태를 잡아준다.
// configureStore.ts import { configureStore } from '@reduxjs/toolkit'; import { createWrapper } from 'next-redux-wrapper'; import rootReducer, { IState } from '@reducers/index'; import { Reducer, AnyAction } from 'redux'; const isDev = process.env.NODE_ENV === 'development'; const createStore = () => { const store = configureStore({ reducer: rootReducer as Reducer<IState, AnyAction>, devTools: isDev, }); return store; }; const wrapper = createWrapper(createStore); export default wrapper;
이제 스토어를 생성한다.
나의 경우 rootReducer와 configureStore의 reducer의 Type문제로 고생했는데 강제로 상태를 정의해주는 방법을 이용했다.
본래라면 Provider를 이용해 store를 넘겨주겠지만, 우리는 next-redux-wrapper를 사용하니 createWrapper를 이용해 생성한 store를 감싸준다.
그리고 아래와 같이 마지막으로 Provider가 아닌 생성한 wrapper를 이용해 App를 감싸주면 사용할 준비가 끝난다.
import React from 'react'; import Head from 'next/head'; import { AppProps } from 'next/app'; import wrapper from '@utils/configureStore'; const App = ({ Component, pageProps }: AppProps): React.ReactElement => ( <> <Head> <title>Test</title> </Head> <Component {...pageProps} /> </> ); export default wrapper.withRedux(App);
이제 아래와 같이 page들에서 SSR로 redux를 사용할 수 있다.
import React from 'react'; import wrapper from '@utils/configureStore'; import { loadTesting } from '@APIs/post'; const Index = (): React.ReactElement => ( <> Index!!! </> ); export const getServerSideProps = wrapper.getServerSideProps((store) => async ({req,res, ...ets}) => { // ({req, res, ...ets})는 ()로 생략해도 무관 await store.dispatch(loadTesting(10)); return { props: {} }; }); export default Index;
'Next.js' 카테고리의 다른 글
NextJS Cypress 설정하기 (0) 2022.02.17 NextJS Image 태그 height auto로 사용하기 (0) 2022.01.11 NextJS Image에서 fallback 활용하기 (0) 2021.09.16 NextJS Firebase@9으로 migration하기 (0) 2021.09.14 NextJS 외부라이브러리 Error : document(or window) is not defined 해결하기 (0) 2021.09.06