[Next.js] - Redux Wrapper

NoowaH·2022년 2월 13일
0

Next.js

목록 보기
9/17
post-thumbnail

Redux Wrapper v7.0+


  • Redux Wrapper v7.0 이후 API의 사용의 큰 변화가 있으며 Next.js 에서 사용하는 Redux 설정을 복습하고 넘어가는 시간

  • 클론코딩 책을 통한 내용에서 outdated 된 방식 개선될 수 있는 코딩구현을 위한 공부

  • 📍 next-redux-wrapper 내용 기반 노트 정리



1. State reconciliation during hydration


  • 리듀서는 꼭 HYDRATE 액션핸들러를 가지고 있어야 한다 (v.6 이후부터 생긴 기능)

  • HYDRATE 액션핸들러는 주입된 리덕스 상태를 기존에 있던 상태에 조화(reconcilitation) 과정을 거쳐야 한다.

💡 상태 조화가 주입과정에서 일어나는 시점

  • getStaticProps getServerSideProps 가 실행되는 page가 열렸을 때 주입(hydrate)이 실행된다

  • 최초 페이지 로드 혹은 기존 페이지 네비게이션에 디스패치 실행된다.

  • 이 때 액션의 payloadstaticGeneration 혹은 SSR 의 상태를 가지고 있으며 기존 클라이언트 리덕스 상태와 합병하는 과정을 거쳐야 한다

// gernerics 와 type utility를 사용하여 라듀서의 타입 생성
export type RootState = ReturnType<typeof rootReducer>;

// RootReducer과 같은 타입을 가진 상태를 생성 후 주입과정에서 비교하며 상태가 바뀔 때마다 기록
let initialRootState: RootState;

const reducer = (state: any, action: any) => {
  if (action.type === HYDRATE) {
    if (state === initialRootState) {
      return {
        ...state, // 이전 state를 사용
        ...action.payload, // 업데이트 됱 데이터 주입
      };
    }
  }
  return rootReducer(state, action); // hydrate가 아닐 땐 기존 rootReducer 반환
};

...


const initStore = () => {
  const store = configureStore({
    reducer,
    devTools: true
  });
  // 주입 후 상태의 값 다음 HYDRATE 시점에서의 비교를 위해  initialRootState의 저장
  initialRootState = store.getState();
  return store;
}

export const wrapper = createWrapper(initStore);

createWrapper


  • 첫 번째 파라미터로 makeStore 함수를 받는다

  • makeStore 함수는 새로운 리덕스 store를 리턴해야 한다

  • createWrapper는 선택적으로 config 설정으러 두 번쨰 파라미터로 받는다

    • debug (optional, boolean : 디버그 로깅

    • serializeState deserializeState : 직렬화 설정을 위한 커스텀 함수 (📍 추가공부 필요)

  • makeStore 가 호출됐을 때, Next.js 컨텍스트를 통해 제공된다.

  • wrapper lifecycle에 따라 NextPageContext, AppContext, getStaticProps, getServerSideProps 중 하나로 제공된다.




Wrapper Life-Cycle


  • 리듀서는 꼭 HYDRATE 액션핸들러를 가지고 있어야 한다 (v.6 이후부터 생긴 기능)

  • HYDRATE 액션핸들러는 주입된 리덕스 상태를 기존에 있던 상태에 조화(reconcilitation) 과정을 거쳐야 한다.


💡 상태 조화가 주입과정에서 일어나는 시점

  • getStaticProps getServerSideProps 가 실행되는 page가 열렸을 때 주입(hydrate)이 실행된다

App & Page

  • HYDRATE

  • App 래벨에서 (pages/_app) HYDRATE 을 할 수 있지만 Automatic Partial Static Export 과의 호환이 떨어짐으로 지양하는 방향을 권장

  • Page level의 주입은 HYDRATE 액션이 2번 실행된다.

  • App.getInitialProps 을 통한 액션 이후 getServerSideProps getStaticProps 액션을 통한 상태 주입



getInitialProp


App.getInitialProps

_app.tsx

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

app.getInitialProps = wrapper.getInitialAppProps(
  (store) => async (context: AppContext) => {
    const myAppInitialProps = App.getInitialProps(context);
    ...
    return { ...myAppInitialProps };
  }
);
  • App.getInitialAppProps(context: AppContext) 를 리턴

Page.getInitialProps

pages/location.tsx

const location: NextPage = () => {
  return <></>;
};

location.getInitialProps = wrapper.getInitialPageProps(
  (store) => async (context: NextPageContext) => {}
);

export default location;
  • _app 레벨에서 wrapping 을 하지 않은 경우 각 페이지별로 wrapping이 가능하지만 권장하는 방법은 아니다

const location: NextPage = () => {
  return <></>;
};

location.getInitialProps = ({ store }: NextPageContext) => {};

export default connect((state: RootState) => state)(location);
  • _app 레벨에서 wrapping 을 한경우 페이지는 따로 wraapping이 필요없이 connect 함수를 사용하여 접근 가능하다

❗️ 라고 문서에 나와있지만 나느 현재 잘 구동되지 않고 있다...



📍 GetInitalProps 사용?

  • getInitialProps를 통해 액션을 디스패치 할 수 있지만 Next.js 9Auto Partial Static Export 호환이 좋지 않아 공식 문서에서도 지양하며 getStaticPropsgetServerSideProps을 권장한다


🤔 Auto Partial Static Export ?

  • Next.js 는 getServerSideProps getInitialProps가 페이지 내에 없는 경우애도 알아서 빌드시 페에지를 html로 만들며 SSR SSG page 둘 다 제공되는 하이브리드 구현

  • ❗️ BUT! 컨스텀 app 컴포넌트 _app 내에서 getInitialProps 를 사용헐 경우 이러한 최적화 기능 off

참고 - LKHcoding's Blog


🤔 아직 이해가 더 필요함

⭐️ 지양하는 방식은 일단 피하자

profile
조하운

0개의 댓글