서스펜스 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로 감싸진 애들은 로딩 잠시 중단
이후에 결과가 나오면 그때 렌더링해준다.
문제상황
로그인 후 헤더의 Login / Logout 상태가 바로 변경되지 않고 새로고침해야 변경됨
•
시도해본 방법
◦
useSessionStorageUserEmail의 useEffect 의존성배열에 userId 추가하여 userId가 바뀌었을 때 set하도록 함 ⇒ 안됨 ㅠㅠ
•
suspense로 감싸기