next-redux-wrapper가 필요한 이유

심재철
Oct 26, 2020

동기

리액트에 리덕스를 붙이는건 어렵지 않다. 왜냐면, 리액트앱에서는 단 하나의 리덕스 스토어만 존재하니까.

하지만, Next를 사용하는 순간 리덕스 스토어가 여러개가 될 수 있다. Next.js는 유저가 요청할때마다 redux store를 새로 생성한다.

그리고 Next.js가 제공하는 getInitialProps, getServerSideProps등에서 리덕스 스토어에 접근할 수 있어야 한다. next-redux-wrapper가 없다면 이것이 불가능하다.

우선 아래 두가지를 설치해주자

yarn add next-redux-wrapper react-redux

설치하고 나서

// 1. 스토어를 생성하는 makeStore 함수를 정의
const makeStore: MakeStore<State> = (context: Context) => createStore(reducer);

// 2. next-redux-wrapper에서 제공하는 createWrapper정의
export const wrapper = createWrapper<State>(makeStore, {debug: true});

이렇게 해준다. next-redux-wrapper는 유저가 페이지를 요청할때마다 리덕스 스토어를 생성해야 하기 때문에 makeStore함수를 정의해서 넘기는것이다.

그리고 나서 아래처럼, app.js에서

import React, {FC} from 'react';
import {AppProps} from 'next/app';
import {wrapper} from '../components/store';

const App: FC<AppProps> = ({Component, pageProps}) => (
<Component {...pageProps} />
);

export default wrapper.withRedux(App)

wrapper의 withRedux HOC로 App컴포넌트를 감싸주면 된다. 그럼 이제 각 페이지의 getInitialProps, getServerSideProps, getStaticProps등에서 리덕스 스토어에 접근이 가능해진다.

_app.js에서 커스텀 getInitialProps를 정의하지마라. 확장하는 순간 next.js의 페이지 최적화 기능을 무효화 시키기 때문이다.

next.js에서 생성한 redux store와 client에서 생성한 redux store는 다르기 때문에 이 둘을 합쳐야 한다.

그래서 이렇게 서버에서 생성한 스토어의 상태를 HYDRATE라는 액션을 통해서 클라이언트에 합쳐주는 작업이 필요한것이다.

action.payload에는 서버에서 생성한 스토어의 상태가 담겨있다. 이 둘을 합쳐 새로운 클라이언트의 리덕스 스토어의 상태를 만든다.

만약에 순수 next.js만 사용하고 next-redux-wrapper를 사용하지 않는다면 우리는 getInitialProps등에서 리덕스 스토어에 접근할 수 없다. 그런 경우엔 axios나 fetch등의 api 라이브러리를 사용해야한다.

--

--