Warning: Prop d did not match.

준혁·2024년 8월 22일

개인 프로젝트

목록 보기
10/15
Call Stack
React
checkForUnmatchedText
node_modules\.pnpm\next@14.2.6_@babel+core@7.25.2_react-dom@18.3.1_react@18.3.1__react@18.3.1\node_modules\next\dist\compiled\react-dom\cjs\react-dom.development.js (32797:1)
diffHydratedProperties
node_modules\.pnpm\next@14.2.6_@babel+core@7.25.2_react-dom@18.3.1_react@18.3.1__react@18.3.1\node_modules\next\dist\compiled\react-dom\cjs\react-dom.development.js (35055:1)
hydrateInstance
node_modules\.pnpm\next@14.2.6_@babel+core@7.25.2_react-dom@18.3.1_react@18.3.1__react@18.3.1\node_modules\next\dist\compiled\react-dom\cjs\react-dom.development.js (36127:1)
prepareToHydrateHostInstance
node_modules\.pnpm\next@14.2.6_@babel+core@7.25.2_react-dom@18.3.1_react@18.3.1__react@18.3.1\node_modules\next\dist\compiled\react-dom\cjs\react-dom.development.js (7246:1)
completeWork
node_modules\.pnpm\next@14.2.6_@babel+core@7.25.2_react-dom@18.3.1_react@18.3.1__react@18.3.1\node_modules\next\dist\compiled\react-dom\cjs\react-dom.development.js (19769:1)
completeUnitOfWork
node_modules\.pnpm\next@14.2.6_@babel+core@7.25.2_react-dom@18.3.1_react@18.3.1__react@18.3.1\node_modules\next\dist\compiled\react-dom\cjs\react-dom.development.js (25963:1)
performUnitOfWork
node_modules\.pnpm\next@14.2.6_@babel+core@7.25.2_react-dom@18.3.1_react@18.3.1__react@18.3.1\node_modules\next\dist\compiled\react-dom\cjs\react-dom.development.js (25759:1)
workLoopConcurrent
node_modules\.pnpm\next@14.2.6_@babel+core@7.25.2_react-dom@18.3.1_react@18.3.1__react@18.3.1\node_modules\next\dist\compiled\react-dom\cjs\react-dom.development.js (25734:1)
renderRootConcurrent
node_modules\.pnpm\next@14.2.6_@babel+core@7.25.2_react-dom@18.3.1_react@18.3.1__react@18.3.1\node_modules\next\dist\compiled\react-dom\cjs\react-dom.development.js (25690:1)
performConcurrentWorkOnRoot
node_modules\.pnpm\next@14.2.6_@babel+core@7.25.2_react-dom@18.3.1_react@18.3.1__react@18.3.1\node_modules\next\dist\compiled\react-dom\cjs\react-dom.development.js (24504:1)
workLoop
node_modules\.pnpm\next@14.2.6_@babel+core@7.25.2_react-dom@18.3.1_react@18.3.1__react@18.3.1\node_modules\next\dist\compiled\scheduler\cjs\scheduler.development.js (256:1)
flushWork
node_modules\.pnpm\next@14.2.6_@babel+core@7.25.2_react-dom@18.3.1_react@18.3.1__react@18.3.1\node_modules\next\dist\compiled\scheduler\cjs\scheduler.development.js (225:1)
MessagePort.performWorkUntilDeadline
node_modules\.pnpm\next@14.2.6_@babel+core@7.25.2_react-dom@18.3.1_react@18.3.1__react@18.3.1\node_modules\next\dist\compiled\scheduler\cjs\scheduler.development.js (534:1) app-index.js:33 
Warning: Prop d did not match. Server: "M15 3h4a2 2 0 0 1 2 2v14a2 2 0 0 1-2 2h-4" Client: "M9 21H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h4"
    at path
    at svg
    at _c (webpack-internal:///(app-pages-browser)/./node_modules/.pnpm/lucide-react@0.427.0_react@18.3.1/node_modules/lucide-react/dist/esm/Icon.js:18:11)
    at eval (webpack-internal:///(app-pages-browser)/./node_modules/.pnpm/lucide-react@0…_react@18.3.1/node_modules/lucide-react/dist/esm/createLucideIcon.js:19:15)
    at span
    at button
    at _c (webpack-internal:///(app-pages-browser)/./src/components/ui/button.tsx:40:11)
    at li
    at ul
    at nav
    at Menu (webpack-internal:///(app-pages-browser)/./src/components/sidebar/admin-panel/menu.tsx:34:11)
    at div
    at aside
    at Sidebar (webpack-internal:///(app-pages-browser)/./src/components/sidebar/sidebar.tsx:27:85)
    at UseClientHydrationStreamProvider (webpack-internal:///(app-pages-browser)/./node_modules/.pnpm/@tanstack+reac…eact-query-next-experimental/build/modern/HydrationStreamProvider.js:22:69)
    at ReactQueryStreamedHydration (webpack-internal:///(app-pages-browser)/./node_modules/.pnpm/@tanstack+reac…query-next-experimental/build/modern/ReactQueryStreamedHydration.js:20:101)
    at QueryClientProvider (webpack-internal:///(app-pages-browser)/./node_modules/.pnpm/@tanstack+reac…de_modules/@tanstack/react-query/build/modern/QueryClientProvider.js:27:11)
    at Providers (webpack-internal:///(app-pages-browser)/./src/states/providers.tsx:16:11)
    at body
    at html
    at RootLayout (Server)
    at RedirectErrorBoundary (webpack-internal:///(app-pages-browser)/./node_modules/.pnpm/next@14.2.6_@b…@18.3.1/node_modules/next/dist/client/components/redirect-boundary.js:74:9)
    at RedirectBoundary (webpack-internal:///(app-pages-browser)/./node_modules/.pnpm/next@14.2.6_@b…18.3.1/node_modules/next/dist/client/components/redirect-boundary.js:82:11)
    at NotFoundErrorBoundary (webpack-internal:///(app-pages-browser)/./node_modules/.pnpm/next@14.2.6_@b…18.3.1/node_modules/next/dist/client/components/not-found-boundary.js:76:9)
    at NotFoundBoundary (webpack-internal:///(app-pages-browser)/./node_modules/.pnpm/next@14.2.6_@b…8.3.1/node_modules/next/dist/client/components/not-found-boundary.js:84:11)
    at DevRootNotFoundBoundary (webpack-internal:///(app-pages-browser)/./node_modules/.pnpm/next@14.2.6_@b…e_modules/next/dist/client/components/dev-root-not-found-boundary.js:33:11)
    at ReactDevOverlay (webpack-internal:///(app-pages-browser)/./node_modules/.pnpm/next@14.2.6_@b…/next/dist/client/components/react-dev-overlay/app/ReactDevOverlay.js:87:9)
    at HotReload (webpack-internal:///(app-pages-browser)/./node_modules/.pnpm/next@14.2.6_@b…dist/client/components/react-dev-overlay/app/hot-reloader-client.js:321:11)
    at Router (webpack-internal:///(app-pages-browser)/./node_modules/.pnpm/next@14.2.6_@b…react@18.3.1/node_modules/next/dist/client/components/app-router.js:207:11)
    at ErrorBoundaryHandler (webpack-internal:///(app-pages-browser)/./node_modules/.pnpm/next@14.2.6_@b…ct@18.3.1/node_modules/next/dist/client/components/error-boundary.js:113:9)
    at ErrorBoundary (webpack-internal:///(app-pages-browser)/./node_modules/.pnpm/next@14.2.6_@b…t@18.3.1/node_modules/next/dist/client/components/error-boundary.js:160:11)
    at AppRouter (webpack-internal:///(app-pages-browser)/./node_modules/.pnpm/next@14.2.6_@b…react@18.3.1/node_modules/next/dist/client/components/app-router.js:585:13)
    at ServerRoot (webpack-internal:///(app-pages-browser)/./node_modules/.pnpm/next@14.2.6_@b…act@18.3.1__react@18.3.1/node_modules/next/dist/client/app-index.js:112:27)
    at Root (webpack-internal:///(app-pages-browser)/./node_modules/.pnpm/next@14.2.6_@b…act@18.3.1__react@18.3.1/node_modules/next/dist/client/app-index.js:117:11)
app-index.js:33 Warning: An error occurred during hydration. The server HTML was replaced with client content in <#document>.
3
on-recoverable-error.js:20 Uncaught 
Error: Text content does not match server-rendered HTML.
    at checkForUnmatchedText (react-dom.development.js:32797:11)
    at diffHydratedProperties (react-dom.development.js:35055:9)
    at hydrateInstance (react-dom.development.js:36127:3)
    at prepareToHydrateHostInstance (react-dom.development.js:7246:3)
    at completeWork (react-dom.development.js:19769:13)
    at completeUnitOfWork (react-dom.development.js:25963:14)
    at performUnitOfWork (react-dom.development.js:25759:5)
    at workLoopConcurrent (react-dom.development.js:25734:5)
    at renderRootConcurrent (react-dom.development.js:25690:9)
    at performConcurrentWorkOnRoot (react-dom.development.js:24504:38)
    at workLoop (scheduler.development.js:256:34)
    at flushWork (scheduler.development.js:225:14)
    at MessagePort.performWorkUntilDeadline (scheduler.development.js:534:21)
react-dom.development.js:16571 Uncaught 
Error: There was an error while hydrating. Because the error happened outside of a Suspense boundary, the entire root will switch to client rendering.
    at updateHostRoot (react-dom.development.js:16571:57)
    at beginWork$1 (react-dom.development.js:18486:14)
    at beginWork (react-dom.development.js:26927:14)
    at performUnitOfWork (react-dom.development.js:25748:12)
    at workLoopSync (react-dom.development.js:25464:5)
    at renderRootSync (react-dom.development.js:25419:7)
    at recoverFromConcurrentError (react-dom.development.js:24597:20)
    at performConcurrentWorkOnRoot (react-dom.development.js:24542:26)
    at workLoop (scheduler.development.js:256:34)
    at flushWork (scheduler.development.js:225:14)
    at MessagePort.performWorkUntilDeadline 

와 진짜 이거때문에 미치고 팔짝뛰다가 1080도 공중제비 조질 뻔 했다.

결과적으로 얘기하자면 zustand store에서 불러오는 로그인 상태를
서버에서 인식하는 것과 클라이언트에서 인식하는 것이 달라서 생긴 문제였다.

내가 로그인 상태로 조건부 렌더링을 하도록 걸어놨는데

<Button
  onClick={handleUserState}
  className="w-full justify-center h-10 mt-5"
  variant="ghost"
  >
	<span className={cn(isOpen ? "mr-4" : "")}>
		{isLoggedIn ? <LogOut size={18} /> : <LogIn size={18} />}
	</span>
	<p className={cn("whitespace-nowrap", isOpen ? "opacity-100" : "opacity-0 hidden")}>
		{isLoggedIn ? "Sign out" : "Sign in"}
	</p>
</Button>

이런식으로..

근데

const { isLoggedIn, logOut } = authStore((state) => ({
    isLoggedIn: state.isLoggedIn,
    logOut: state.logout
  }))

  const handleUserState = () => {
    if (isLoggedIn) {
      logOut();
    } else {
      router.push('/login')
    }
  };

로그인 상태를 불러오는 부분이 useEffect를 사용하지 않고 그냥 불러오는 식으로 구현했을 때 서버와 클라이언트의 인식이 달라 계속 하이드레이션 오류가 났다.

useEffect(() => {
   // 클라이언트 사이드에서만 상태를 읽도록 설정
   const { isLoggedIn } = authStore.getState();
   setIsLoggedIn(isLoggedIn);
 }, []);

 const handleUserState = () => {
   if (isLoggedIn) {
     authStore.getState().logout();
   } else {
     router.push('/login');
   }
 };

이렇게 csr에서만 상태를 읽도록 설정하니 해결할 수 있었다.
글로는 짧게 적었지만 이거 한다고 한 세시간 박았다 하..
참 부질없는 시간이었을지도..
해결했으니 됐다..

20:46 추가)

이렇게 해두니까 마운트 할 때만 로그인 정보를 업데이트 해서 로그아웃 버튼을 눌러도 버튼이 바뀌지 않는 문제가 생겼다 ㅋㅋㅋ 오류 생길거라고 예상했던 부분이라 바로 고치긴 했는데
아휴.. 진짜 힘드네

const handleClick = () => {
  setIsClicked(prevState => !prevState);
}

useEffect(() => {
  // 클라이언트 사이드에서만 상태를 읽도록 설정
  const { isLoggedIn } = authStore.getState();
  setIsLoggedIn(isLoggedIn);
}, [handleClick]);

const handleUserState = () => {
  if (isLoggedIn) {
    authStore.getState().logout();
    handleClick();
    console.log(isLoggedIn)
  } else {
    router.push('/login');
    handleClick();
    console.log(isLoggedIn)
  }
};

대강 이런식으로 버튼 클릭했을 때 실행하는 함수에 handleclick 넣어주고 의존성 배열에 handleclick 넣어서 버튼 클릭할 때 마다 업데이트 하도록 바꿔줬다 일단은 해결
또 오류 생기면 업데이트 하겠다..

profile
좌충우돌 초보 개발자의 문제 풀이 저장소

0개의 댓글