거의 알고리즘 일기장

nextjs에서 zustand persist 사용시 주의할점! 본문

web

nextjs에서 zustand persist 사용시 주의할점!

건우권 2023. 2. 18. 19:45

nextjs 초심자 권모씨 평소와 같이 zustand persist를 사용하던중 content mismatch 문제가 발생하는데...

 

??

이게 어떻게 된일일까??

사건의 전말은 이렇다!

//...
const Mismatch = () => {
  const user = useUser();

  return <div>{user?.name ?? 'user is null'}</div>;
};

상황

얼핏보면 문제가 없어보인다.

 

하지만, 피해자는 이 코드의 환경이 nextjs 라는 사실을 간과했다!!

문제는 store hydrate가 되는 지점이다!!

html -> store hydrate -> react rehydrate 이런식으로 store hydrate가 react의 rehydrate 되기 직전에 된다!!

 

 

이게 왜 문제가 되는지는 react docs의 hydrate에 대해 써져있는 글을 보면 알수있다!

Caveats 

  • hydrate expects the rendered content to be identical with the server-rendered content. React can patch up differences in text content, but you should treat mismatches as bugs and fix them.

 

그러니까 정리하자면, 이 친구는 지금 봤을때 rendering 된 컨텐츠가 서버에서 rendering된 content와 일치할것이라고 생각하는데, store hydrate를 하면서 중간에 바뀌니까 에러를 뱉는거다!

 

뭔 개소리야?

그림을 곁들여 설명하자면,

 

1. 서버에서는 user is null이라는 content가 왔다!

2. store hydrate 과정에서 저 user is null이 test로 바뀌었다. (storage에 이미 test로 저장되어있었기 때문에)

3. react가 rehydrate 하려는데, 나는 user is null일줄 알았는데, rendering된 걸 봤더니 test네?.. 에러뱉을래

 

이제 이해가 되었을것이다!!

진짜 그런지 확인해보려고 log와 profiler도 한번 봤는데 그런듯하다!
(profiler에서 store 관련 함수가 먼저 실행되는걸 확인했는데... 다시 찾아보려니까 안보인다. 눈알빠지는줄)

log

이제 그래서 해결책은 뭔디?

1. useEffect 안에서 쓴다!

useEffectsms client라는게 명확하다. 그러므로 이렇게 useState를 따로 선언해서 쓰면 된다.

//...
const Mismatch = () => {
  //zustand store
  const user = useUser();

  const [userState, setUserState] = useState<User>();

  //client
  useEffect(() => {
    if (!user) return;

    setUserState(user);
  }, [user]);

  return <div>{userState?.name ?? 'user is null'}</div>;
};

2. server와 client의 sync를 맞춰준다. 

이 분은 redis를 이용해서 한거같은데 확인해보면 좋을것 같다.

https://velog.io/@yhg0337/Redis-with-Persistant-storage

 

마지막. Redis를 활용한 Persistant storage적용하기

Hydration과 SSR에 대한 이해를 통해 zustand에 적용할 수 있는 redis를 활용한 persistant-storage를 구현해봅니다.

velog.io


 

https://nextjs.org/docs/messages/react-hydration-error

 

react-hydration-error | Next.js

React Hydration Error While rendering your application, there was a difference between the React tree that was pre-rendered (SSR/SSG) and the React tree that rendered during the first render in the Browser. The first render is called Hydration which is a f

nextjs.org

반응형
Comments