본문으로 바로가기

일반적인 React 처럼 사용하면 되지만 약간 다른 부분이 있어 정리해보았습니다.

 

우선 일반적인 React + Redux 사용법은

https://darrengwon.tistory.com/184?category=889133

https://darrengwon.tistory.com/556?category=889133

여기를 참고합시다.

 

차이점 1 ) 우선 Provier로 감쌀 최상위 컴포넌트는 page/_app.js 입니다. React 때 처럼 index.js가 없거든요.

 

차이점 2 ) Next에서는 store를 최상위 컴포넌트의 props에 가져와야 합니다. 그런데 _app.js에 있는 컴포넌트에 props가 존재할 수가 없죠. HOC을 이용해서 한번 감싸줘야 합니다. 다음 패키지(next-redux-wrapper)를 설치 한 후 감싸줍시다.

 

* next-redux-wrapper 5.0.0 버전기준입니다. 6버전 부터는 방식이 달라졌습니다. Next9.3 이후부터는 6버전을 사용하기를 권장하고 있습니다. 아무래도 6버전을 써야겠죠.

 

(https://github.com/kirill-konshin/next-redux-wrapper) 여기를 참고합시다.

 

npm i next-redux-wrapper

 

5버전 + getInitialProps

 

store에 enhancer도 가미했습니다.

import withRedux from "next-redux-wrapper";
import { createStore } from "redux";
import { Provider } from "react-redux";
import Rootreducer from "../reducers";


const MyApp = ({ Component, store }) => {
  return (
    <Provider store={store}>
        <Component />
    </Provider>
  );
};


export default withRedux((initialState, options) => {
  const middlewares = [];
  const enhancer = compose(
    applyMiddleware(...middlewares),
    typeof window !== "undefined" &&
      window.__REDUX_DEVTOOLS_EXTENSION__ &&
      window.__REDUX_DEVTOOLS_EXTENSION__()
  );
  const store = createStore(Rootreducer, initialState, enhancer);
  return store;
})(MyApp);

 

어... 그런데 어느 순간 부터 legacy 사용이라고 경고를 날리기 시작했습니다. 아무래도 6버전의 사용방법으로 바꿔야할 것 같네요.

 

6버전 + next 9 이상의 getStaticProps, getServerSideProps 

 

5버전과 많이 달라졌습니다.

 

주의할 점은 Provider로 감싸지 않는다는 점, next-redux-wrapper가 알아서 store를 실은 후 자동으로 감싸준다는 점입니다.

 

또, 이상하게 redux devtools 가 오류가 나서 패키지를 설치해서 연결했습니다. 앞으로도 패키지를 설치하는 방향으로 데브 툴즈를 쓸 것 같습니다.

(https://www.npmjs.com/package/redux-devtools-extension)

import { createStore, applyMiddleware, compose } from "redux";
import { createWrapper } from "next-redux-wrapper";
import { createLogger } from "redux-logger";
import { composeWithDevTools } from "redux-devtools-extension";

import rootReducer from "./index";

const configureStore = () => {
  const logger = createLogger();

  const enhancer = compose(composeWithDevTools(applyMiddleware(logger)));

  const store = createStore(rootReducer, enhancer);
  return store;
};

const wrapper = createWrapper(configureStore, { debug: true });

export default wrapper;

 

./_app.js

import wrapper from "../reducers/configureStore";

function MyApp({ Component, pageProps }) {
  return (
    <>
      <AppLayout>
        <Component {...pageProps} />
      </AppLayout>
    </>
  );
}

// 감싸기
export default wrapper.withRedux(MyApp);

 

각 세부 페이지의 getInitialProps, getServerSideProps와의 결합

(wrapper로 감싸줘야 context에 store가 생기고, 이를 이용해 dispatch를 날릴 수 있습니다.)

export const getServerSideProps = wrapper.getServerSideProps(
  async (context) => {
    let { page } = context.query;
    if (page === undefined) page = 1;

    
    context.store.dispatch({ type: POST_REQUEST });

    return {
      props: {}, // will be passed to the page component as props
    };
  }
);

 

 

 

만약 Redux-Saga를 사용하실 예정이라면 next-redux-saga를 설치하고 전체를 wrapping해야 합니다.

https://github.com/bmealhouse/next-redux-saga

 

bmealhouse/next-redux-saga

redux-saga HOC for Next.js. Contribute to bmealhouse/next-redux-saga development by creating an account on GitHub.

github.com

 

 

 


darren, dev blog
블로그 이미지 DarrenKwonDev 님의 블로그
VISITOR 오늘 / 전체