nextjs
에서 redux
를 사용하기 위해서는 next-redux-wrapper
가 필수적으로 필요한 이유가 궁금했다.
본문 일부 내용 번역
정적 앱용 Redux
를 설정하는 것은 다소 간단하다 모든 페이지에 제공되는 단일 Redux
저장소를 만들어지기 때문에.
Next.js static site generator
or server side rendering
이 관련되면 Redux
연결 구성 요소를 렌더링하기 위해 서버에 다른 저장소 인스턴스가 필요하기 때문에 작업이 복잡해지기 시작합니다.
또한 초기 값 관련해서 redux
의 store
에 접근해야 할 수 도 있다.
next-redux-wrapper
는 자동으로 스토어 인스턴스를 생성하고 모두 동일한 상태를 갖도록 합니다.
이해 과정
실제로 처음 nextjs 를 사용할때 예상과 달리 store 내용이 초기화 되고 오류를 만난 기억이 있다.
※ 여기서부터 내가 이해한 부분 오류에 주의
nextjs
로 SSR
를 구현한다고 봤을 때 React
처럼 CSR
과 달리 웹서버에서 새로 페이지를(html 뿐만 아니라 데이터 리소스까지) 구성해 전달해준다.
이 말은 즉 redux 의 store 내용을 공유받지 못하면 화면을 구성하는데 문제가 생길 수 있다.
SSR
인 상황에서 문제없이 처리하려면 store
의 내용을 공유하여 웹서버입장에서 기존 redux 데이터와 이후 변경되는 데이터들을이 합쳐진 redux 상태를 참고하여 화면을 구성해야한다.
이 과정을 자연스럽게 해주는 라이브러리가 next-redux-wrapper
이다.
위 과정을 자세히 간단하게 설명하면 클라이언트의
redux store
에 서버에서 처리한 store 내용(예 : server side rendering 에서 dispatch 한 내용) 을 받아Hydration
이 된다. (store 가 합쳐져 생성된다)
적용
※ redux-toolkit
적용한 예제이며 redux-toolkit
에서 import 한 configureStore()
부분은 무시해도 된다 createStore()
같은 store
생성 부분만 들어가면 된다. + ts 도 적용됨 타입은 참고만
store.ts
``next-redux-wrapper는 유저가 페이지를 요청할때마다
reduxstore`를 생성하기 때문에 makeStore함수를 정의해서 넘기는것이다.
본문 중 :
createWrapper
함수는 첫makeStore
번째 인수로 받아들입니다. 이 함수는 호출될 때마다makeStore
새로운 Redux 인스턴스를 반환해야 합니다 .
// store.ts
const makeStore = () => configureStore({
reducer: rootReducer as Reducer<ReducerStates, AnyAction>,
...
})
export type AppStore = ReturnType<typeof makeStore>; // `store` type
export const wrapper = createWrapper<AppStore>(makeStore);
rootReducer.ts
위에 설명한 Hydration
과정을 구현한 부분action type
을 next-redux-wrapper
에서 import
해온 HYDRATE
를 설정하고 그 외 리듀서 내용도 추가한다.
// rootReducer.ts
import { HYDRATE } from 'next-redux-wrapper';
...
const rootReducer:RootReducerType = (state, action) => {
switch (action.type) {
case HYDRATE:
return action.payload
default: {
const combinedReducer = combineReducers({
...
})
return combinedReducer(state, action)
}
}
};
pages/_app.ts
최상위 컴포넌트에 Provider
로 감싸서 마무리 최종으로 적용 시킨다.
// pages/_app.ts
import { Provider } from 'react-redux';
import { AppProps } from 'next/app';
import { wrapper } from '@store/store';
...
export default function MyApp({ Component, ...rest }: AppProps) {
const { store, props } = wrapper.useWrappedStore(rest);
return (
<Provider store={store}>
<Component {...props.pageProps} />
</Provider>
)
}
참고
https://simsimjae.medium.com/next-redux-wrapper%EA%B0%80-%ED%95%84%EC%9A%94%ED%95%9C-%EC%9D%B4%EC%9C%A0-5d0176209d14
https://helloinyong.tistory.com/315
'nextjs' 카테고리의 다른 글
커스텀 crousel (nextjs + ts + styled-components) (0) | 2023.04.20 |
---|---|
Next.js 에 <Link /> 는 무엇인가 (0) | 2023.04.06 |
Next.js getServerSideProps 에서 페이지 이동 방법 (0) | 2023.03.31 |
nextjs 기타 지원 기능 (0) | 2023.02.02 |
nextjs 기본 및 페이지 개념 (0) | 2023.02.02 |