🖊️

2024. 04. 09. 회의록

서스펜스 fallback
페이지별로 로딩
컴포넌트별로 로딩도 가능
/* 예시 */ <Suspense fallback={<p>Loading weather...</p>}> <Weather /> </Suspense>
TypeScript
복사
'use client'; import useLoginUserId from '@/hooks/useLogin/useLoginUserId'; import { useReadLoginUserId } from '@/hooks/useLogin/useSetEmailToApi'; import useSetSessionStorage from '@/hooks/useLogin/useSetStorage'; // import useSessionStorageUserEmail from '@/hooks/useLogin/useSessionStorageUserEmail'; import { signOut } from 'next-auth/react'; import Link from 'next/link'; export default function LoginState() { // const userEmail = useUserEmail(); const userEmail = typeof window !== 'undefined' ? sessionStorage.getItem('userEmail') : null; // const userEmail = useSessionStorageUserEmail(); const handleLogout = async () => { sessionStorage.removeItem('userEmail'); await signOut({ redirect: true, callbackUrl: '/' }); }; // 훅 호출 useSetSessionStorage(); useReadLoginUserId(userEmail); useLoginUserId({ userEmail }); return <div>{userEmail ? <button onClick={handleLogout}>Logout</button> : <Link href="/hello">Login</Link>}</div>; }
TypeScript
복사
Uncaught Error: Minified React error #418; visit https://reactjs.org/docs/error-decoder.html?invariant=418 for the full message or use the non-minified dev environment for full errors and additional helpful warnings.
TypeScript
복사
ERROR Error: Minified React error #418 
'use client'; import useLoginUserId from '@/hooks/useLogin/useLoginUserId'; import useSessionStorageUserEmail from '@/hooks/useLogin/useSessionStorageUserEmail'; import { useReadLoginUserId } from '@/hooks/useLogin/useSetEmailToApi'; import useSetSessionStorage from '@/hooks/useLogin/useSetStorage'; import { signOut } from 'next-auth/react'; import Link from 'next/link'; export default function LoginState() { const userEmail = useSessionStorageUserEmail(); const handleLogout = async () => { sessionStorage.removeItem('userEmail'); await signOut({ redirect: true, callbackUrl: '/' }); }; // 훅 호출 useSetSessionStorage(); useReadLoginUserId(userEmail); useLoginUserId({ userEmail }); return <div>{userEmail ? <button onClick={handleLogout}>Logout</button> : <Link href="/hello">Login</Link>}</div>; }
TypeScript
복사
import { useEffect, useState } from 'react'; export default function useSessionStorageUserEmail() { const [userEmail, setUserEmail] = useState(''); useEffect(() => { const userEmailFromStorage = sessionStorage.getItem('userEmail'); if (userEmailFromStorage) { setUserEmail(userEmailFromStorage); } }, []); return userEmail; }
TypeScript
복사
next.js 14버전으로 넘어오면서 client side에서 hydration이 된다..
use client를 써도 html이 넘어온다.. window과 관련있는 애들은 html이 넘어왔는데, 서버와 클라이언트 사이에 html이 달라서
브라우저 환경에서 쓰는 객체를 hook 없이 썼을 때 나오는 에러…
use client는 사실 client가 아니다?!
sessionStorage가 서버 api가 아니라 api? ssr에서 렌더링을 할 때,
hydration failed : build 결과물 ≠ client 결과물이 다르다 → useEffect 안에서는 해결이 된다..! 라이브러리 쓴다…?
useLocalStrorageState 라이브러리 사용
suspense는 컴포넌트로 감싸기?
suspense로 감싸진 애들은 로딩 잠시 중단
이후에 결과가 나오면 그때 렌더링해준다.
minified 오류 해결!!
오류가 났던 이유)
클라이언트 컴포넌트가 완전히 클라이언트 컴포넌트가 아니다? use Client를 써도 HTML 이 넘어옴 (hook과 관련없는애들) 서버에서 준 HTML이랑 js가 하이드레이션 해야하는 HTML이랑 다름?
메이저
이전버전과 호환되지 않는 기능추가
마이너
feat
패치
style, fix
문제상황

로그인 후 헤더의 Login / Logout 상태가 바로 변경되지 않고 새로고침해야 변경됨

시도해본 방법
useSessionStorageUserEmail의 useEffect 의존성배열에 userId 추가하여 userId가 바뀌었을 때 set하도록 함 ⇒ 안됨 ㅠㅠ
getServerSession으로 깜박임을 막기?
서버에서 받아오기
될지안될지 몰라
유저인터ㅓ랙션이 필요하면 클라이언트니까.. 안될거다?
suspense로 감싸기

useSession의 state에 따라서 바꿔보기? (성공) - loading, authenticated, unauthenticated 상태 제공해줌