From fda4d8051d292ef992c41d8015dd56879e785381 Mon Sep 17 00:00:00 2001 From: Fredrik Monsen Date: Tue, 5 Nov 2024 09:03:01 +0100 Subject: [PATCH] prevent hydration error --- package-lock.json | 2 +- src/components/Header.tsx | 11 +++++++++-- src/hooks/usePersistState.ts | 7 +++++-- 3 files changed, 15 insertions(+), 5 deletions(-) diff --git a/package-lock.json b/package-lock.json index 9bfbc51..83da1ba 100644 --- a/package-lock.json +++ b/package-lock.json @@ -11,7 +11,7 @@ "@nextui-org/react": "2.4.8", "@prisma/client": "5.20.0", "@react-stately/data": "3.11.6", - "@sentry/nextjs": "^8.32.0", + "@sentry/nextjs": "8.32.0", "formik": "2.4.6", "framer-motion": "11.8.0", "next": "14.2.13", diff --git a/src/components/Header.tsx b/src/components/Header.tsx index 330621b..bc76ca2 100644 --- a/src/components/Header.tsx +++ b/src/components/Header.tsx @@ -1,7 +1,7 @@ 'use client'; import {Link, Navbar, NavbarBrand, NavbarContent, NavbarItem} from '@nextui-org/react'; -import React from 'react'; +import React, {useEffect, useState} from 'react'; import {usePathname, useRouter} from 'next/navigation'; import SearchBar from '@/components/SearchBar'; import Image from 'next/image'; @@ -12,10 +12,17 @@ import {UserDetails} from '@/components/UserDetails'; export default function Header() { const { authenticated , user } = useAuth(); const router = useRouter(); + const [ isMounted, setIsMounted ] = useState(false); const pathname = usePathname() || ''; const titlepageRegex = /^\/\d+$/; + // To prevent hydration error when displaying the user details as these are rendered from session storage + useEffect(() => { + setIsMounted(true); + return () => setIsMounted(false); + }, []); + return ( @@ -36,7 +43,7 @@ export default function Header() { } - { authenticated ? ( + { authenticated && isMounted ? ( <> diff --git a/src/hooks/usePersistState.ts b/src/hooks/usePersistState.ts index edc71c3..8ec2442 100644 --- a/src/hooks/usePersistState.ts +++ b/src/hooks/usePersistState.ts @@ -1,10 +1,13 @@ import {useEffect, useMemo, useState} from 'react'; +// Check if window is defined (i.e. if we are in the browser) +const storage = typeof window !== 'undefined' ? sessionStorage : null; + // Hook to persist state in session storage export default function usePersistState(id: string, initialValue: T): [T, (newState: T) => void] { const value = useMemo(() => { - const sessionStorageValue = sessionStorage.getItem('state:' + id); + const sessionStorageValue = storage?.getItem('state:' + id); if (sessionStorageValue) { return JSON.parse(sessionStorageValue) as T; @@ -18,7 +21,7 @@ export default function usePersistState(id: string, initialValue: T): [T, (ne useEffect(() => { const stateStr = JSON.stringify(state); - sessionStorage.setItem('state:' + id, stateStr); + storage?.setItem('state:' + id, stateStr); // eslint-disable-next-line react-hooks/exhaustive-deps }, [state]);