본문 바로가기

Develop/Next.js

[Develop/Next.js] Next.js hydrate시 redux state 초기화

Next.js

Next.js hydrate시 redux state 초기화

Next.js에는 hydrate 개념이 존재한다. 아마 기존 Next.js를 공부하고 있는 개발자라면 이미 개념을 이해하고 있을 것이다.

하지만 간단하게 설명하자면 Next.js는 SEO를 위해 사용한다 해도 과언이 아닐 정도로 많은 개발자나 회사들이 ServerSideRendering을 위하여 사용하고 있을 것이다.

 

Hydrate 즉 Hydration 은서버사이드렌더링을 통한 이미 그려져 불러온 HTML들과 더불어 번들링 된 JS파일들을 클라이언트 단에서 상호작용할 수 있도록 융합되는 과정을 말한다. 즉, 초기 HTML을 로드하고 클라이언트 사이드 동작이 되도록 React가 동작하도록 JS를 불러와 합쳐주는 것이 이런 과정이 물이 흐르는 듯한 느낌은 준다고 하여 Hydrate라 불린다고 한다.

 

출처: https://aboutmonica.com/blog/server-side-rendering-react-hydration-best-practices

 

최근 Next.js와 Redux, Redux-saga, SWR 등 여러 조합으로 개발을 하게 되면서 페이지 이동시 서버사이드가 동작되면서

Redux의 상태값이 초기화되는 점을 발견하였고 처음에는 조금 의문이었다. 머릿속으로는 어느 정도 이해가 되는 부분이었지만

이게 방법이 없을까? 이렇게 된다면 Redux의 장점이라고 생각했던 부분중에 하나가 없어지는 게 아닌가...라는 생각

 

서버사이드의 데이터를 가져오면서 기존 클라이언트 사이드에서 돌아가는 state들이 초기화 되는것이 처음에는 이해가 가지 않았다.

물론 지금도 내가 이해한 부분이 확실한가 의문은 들지만, 정리한 바로는 페이지 이동 시 Hydrate 될 때마다 Redux는 새로운 Store를 만들게 된다. 그리고 hydrate 되면서 ssr에서 적용한 state들을 넣어준다.

 

물론 그럴 수도 있고 안 그럴수도 있지만 글쓴이 같은 경우에 페이지 이동후에도 Redux state가 유지가 돼야 하는 부분이 있었다.

그럼 방법은 뭐가 있을까? 

 

첫 번째 방법으론 기존에도 이전 회사에서 로그인 여부 등의 이슈로 인하여 사용했던 redux-persist이다. 이름 그대로 redux에 영속성을

부여하는 모듈인데 내부적으로 cookie나 storeage에 redux 데이터를 저장하고 사용하게 된다.

 

두 번째는 rootReducer에서 HYDRARE를 적용하지 않고 extraReducer를 사용하여 각 state의 reducer에서 필요한 해당 action에서만 HYDRATE를 시켜준다. 이렇게 하면 물론 HYDRATE를 하는 페이지에서는 그 해당 스토어는 hydration 되면서 초기화되겠지만

다른 스토어의 값들은 초기화가 이뤄지지 않는다.

 

예를 들어 count와 user라는 각 state를 만들었다고 가정하면 rootReducer에서는 아래와 같이 HYDRATE 하는 로직을 제거하고

const rootReducer = (state: State, action: AnyAction): State => {
  switch (action.type) {
    case HYDRATE: // 모든 store가 확인하지 않도록 해당케이스 제거
      return action.payload;
    default: {
      return combineReducer(state, action);
    }
  }
};

 

user라는 store에서만 HYDRATE가 이루어지도록 extraReducer를 통하여 변경하여 준다.

  // store/user/reducer.ts
  ... 각 리듀서
  extraReducers: {
    [HYDRATE]: (state, action) => {
      if (action.payload.user) {
        state.memNo = action.payload.user.memNo;
      }
    },
  }

이렇게 하여주면 해당 actions에서만 hydration이 이루어지면서 user store만 초기화되게 된다. 두 번째 방법은 아무래도 조금 더 손이 많이 가는 작업으로 생각이 된다. 아마도 여러 블로그를 참고하면서 공부 한결과는 서버사이드를 위해 redux를 사용할 경우 애초에 클라이언트 사이드와 서버사이드의 store를 구분하여 만들거나 persist를 사용하는 거로 보인다.

 

나중에 회사나 개인적인 토이 프로젝트를 통해 조금 더 공부하고 더 나은 방법을 모색해야 해봐야 하지만 몰랐던 점을 알았고 알아가는 과정이라 생각한다. 또 누군가에게는 조금이나마 도움이 되었으면 한다. 

 

👆 이 점은 아직도 미숙하고 조금 더 공부해야 하기에 더 좋은 방법이나 공부하면 좋을 지식이 있다면 댓글로 공유하여 주세요!

'Develop > Next.js' 카테고리의 다른 글

[Develop/Next.js] Next.js에 구글 애널리틱스 적용  (0) 2022.03.02