Redux-Wrapper 는 Next.js 에서 서버렌더링 시 state 를 동기화하는 라이브러리다. 기존 redux 는 클라이언트에서 store 를 생성하고 저장하는데, next.js 는 서버에서 동작하는 상태가 있기 때문에 이와 같은 라이브러리의 필요성이 생겼다. 그런데 나를 포함한 몇몇 사람들은 서버렌더링 상태와 클라이언트 상태의 동기화에 대해 잘못 이해하는 부분이 있다.
redux-wrapper 사용 시 주의할 개념
-
매 페이지 로드마다 Store 는 초기화된다. 즉 페이지 새로고침하면 state가 유지되지 않는다.
( next.js 에서 router.push() 를 하면 새로고침이 아니라 컴포넌트 변경이다. router.push()를 해서 페이지 이동을 할 경우 redux 상태는 유지된다. )
-
server의 store 와 client의 store 가 독립적으로 유지한다. 두 store 의 상태를 동기화하려면 next-redux-cookie-wrapper 를 사용해라.
-
getIntialProps / getStaticProps / getServerSideProps 시에 dispatch(action) 한 내용이 client 에 전달되고, HYDRATE 되어 Client 에서 저장된다.
-
getIntialProps / getStaticProps / getServerSideProps 에서 dispatch 한 state 는 서버에서 다시 참조 가능하다. 리로드만 안하면 이전 state 값을 유지한다.
How it works
- Phase 1:
getInitialProps/getStaticProps/getServerSideProps
- wrapper 가 server-side 초기화된 store 를 생성한다. (makeStore)
- 이 과정을 통해 Request 와 Response 의 객체를 makeStore 에 제공한다.
- wrapper 가 getServerSideProps 함수를 부르고 생성한 store를 제공한다.
- Next.js가 store의 state와 getServerSideProps 에서 리턴받은 props 를 받는다.
- Phase 2: SSR
- wrapper 가 makeStore를 사용해 빈 store 를 생성한다.
- wrapper 는 이전에 state 상태를 payload 에 담아 HYDRATE action 을 dispatch 한다.
- 이 store 는 _app 이나 page component 의 property 으로 전달된다.
- 연결된 컴포넌트는 store의 state를 변경할 수 있지만, 변경된 state가 client 에게 전달되지 않는다.
- Phase 3: Client
- wrapper 가 새로운 store 를 만든다
- wrapper 가 Phase1 에서 사용된 payload 를 이용해 HYDRATE action 을 dispatch 한다.
- store 가 _app 이나 page 의 component property 로 전달된다.
- wrapper 는 client window object에 store 를 유지하고, HMR 상태에서 Restored 된다.
state는 새로고침 시 유지되지 않는다! (i.e. Phase1 은 항상 빈 상태로 시작한다). 새로고침을 하면 리셋된다.
https://github.com/kirill-konshin/next-redux-wrapper?tab=readme-ov-file#state-reconciliation-during-hydration