Redux Wrapper for Next.js

Jung taeWoong·2021년 12월 11일
0

Next.js

목록 보기
5/5
post-thumbnail

Redux Wrapper

  • next-redux-wrapper
  • Next.js와 같은 SSR은 서버에서 데이터를 사용하여 화면을 미리 만들게되는데 서버에 Redux 데이터를 사용하기 위해 연결하는 장치
$ npm i next-redux-wrapper

설정

store/configureStore.js

  • createWrapper: Next.js에서 사용하는 라이프사이클 (getServerSideProps, getStaticProps)과 Redux를 결합시킴으로써 접근가능하게 만듦
    • createWrapper(store, option)
    • option: {debug: boolean}: 리덕스에 관한 상세정보들을 로깅
import { createWrapper } from 'next-redux-wrapper';
import { applyMiddleware, createStore, compose } from 'redux';
import createSagaMiddleware from 'redux-saga';
import { composeWithDevTools } from 'redux-devtools-extension';

import reducer from '../reducers';
import rootSaga from '../sagas';

const configureStore = (context) => {
  const sagaMiddleware = createSagaMiddleware();
  const middlewares = [sagaMiddleware];
  const enhancer = process.env.NODE_ENV === 'production'
    ? compose(applyMiddleware(...middlewares))
    : composeWithDevTools(
      applyMiddleware(...middlewares),
    );
  const store = createStore(reducer, enhancer);
  store.sagaTask = sagaMiddleware.run(rootSaga);
  return store;
};

const wrapper = createWrapper(configureStore, {debug: process.env.NODE_ENV === 'development'});

export default wrapper;

reducer/index.js

  • HTDRATE: next-redux-wrapper를 사용할 때 필요한 액션, 서버에서 실행된 리덕스 상태 결과물을 클라이언트에서 HYDRATE라는 액션을 통해 전달됨
import { HYDRATE } from 'next-redux-wrapper';
import { combineReducers } from 'redux';

import otherReducer from './other';
import other2Reducer from './other2';

const rootReducer = (state, action) => {
  // 루트 리듀서의 전체 상태를 덮어씌우기 위함
  switch (action.type) {
    case HYDRATE:
      console.log('HYDRATE', action);
      return action.payload;

    default: {
      const combineReducer = combineReducers({
        otherReducer1,
        otherReducer2,
      });
      return combineReducer(state, action);
    }
  }
}

export default rootReducer;

_app.js

  • wrapper.withRedux(): Hight-Order-Component로 최상단 컴포넌트를 감싸주게되면 각 페이지의 next.js lifecylce에서 스토어에 접근이 가능해진다.
  • Next.js는 기존 react에서 redux를 사용하기 위해 Provider로 감싸는 설정을 하지 않아도 자체적으로 제공해준다.
    • 오히려 위의 설정을 해준다면 중복이기 때문에 설정하지 않는것을 추천
import wrapper from './store/configureStore';

const App = ({ Component }) => {
  return (
    <>
      <Component />
    </>
  )
}

epxort default wrapper.withRedux(App);

Life Cycle Method 결합

  • 화면을 그리기 전에 리덕스 데이터를 서버쪽에서 먼저 실행해주어야 한다.
  • wrapper는 store/configureStore.js에서 만들어둔 store를 감싼 객체
  • wrapper.getServerSideProps에서 dispatch한 결과물을 HYDRATE로 전달하게 된다.
export const getServerSideProps = wrapper.getServerSideProps((store) => async ({req, res, ...etc}) => {
  store.dispatch({
    type: LOAD_MY_INFO_REQUEST,
  });

  store.dispatch({
    type: LOAD_POSTS_REQUEST
  })
  
   // request 후에 success와 failure를 반환할때까지 기다려주기 위해 작성
  // import { END } from 'redux-saga';
  store.dispatch(END);
  // configureStore에 등록했던 store.sagaTask = sagaMiddleware.run(rootSaga);
  await store.sagaTask.toPromise();
});
profile
Front-End 😲

0개의 댓글