Redux Wrapper v7.0
이후 API의 사용의 큰 변화가 있으며 Next.js 에서 사용하는 Redux 설정을 복습하고 넘어가는 시간
클론코딩 책을 통한 내용에서 outdated
된 방식 개선될 수 있는 코딩구현을 위한 공부
📍 next-redux-wrapper 내용 기반 노트 정리
리듀서는 꼭 HYDRATE
액션핸들러를 가지고 있어야 한다 (v.6 이후부터 생긴 기능)
HYDRATE
액션핸들러는 주입된 리덕스 상태를 기존에 있던 상태에 조화(reconcilitation
) 과정을 거쳐야 한다.
getStaticProps
getServerSideProps
가 실행되는 page가 열렸을 때 주입(hydrate)이 실행된다
최초 페이지 로드 혹은 기존 페이지 네비게이션에 디스패치 실행된다.
이 때 액션의 payload
는 staticGeneration
혹은 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
중 하나로 제공된다.
리듀서는 꼭 HYDRATE
액션핸들러를 가지고 있어야 한다 (v.6 이후부터 생긴 기능)
HYDRATE
액션핸들러는 주입된 리덕스 상태를 기존에 있던 상태에 조화(reconcilitation
) 과정을 거쳐야 한다.
getStaticProps
getServerSideProps
가 실행되는 page가 열렸을 때 주입(hydrate)이 실행된다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;
const location: NextPage = () => {
return <></>;
};
location.getInitialProps = ({ store }: NextPageContext) => {};
export default connect((state: RootState) => state)(location);
❗️ 라고 문서에 나와있지만 나느 현재 잘 구동되지 않고 있다...
getInitialProps
를 통해 액션을 디스패치 할 수 있지만 Next.js 9
의 Auto Partial Static Export
호환이 좋지 않아 공식 문서에서도 지양하며 getStaticProps
와 getServerSideProps
을 권장한다🤔 Auto Partial Static Export
?
Next.js 는 getServerSideProps
getInitialProps
가 페이지 내에 없는 경우애도 알아서 빌드시 페에지를 html로 만들며 SSR
SSG
page 둘 다 제공되는 하이브리드 구현
❗️ BUT!
컨스텀 app 컴포넌트 _app
내에서 getInitialProps
를 사용헐 경우 이러한 최적화 기능 off
참고 - LKHcoding's Blog
🤔 아직 이해가 더 필요함
⭐️ 지양하는 방식은 일단 피하자