app/layout.tsx
"use client";
import "./globals.css";
import React from "react";
import Alert from "@/app/ui/alert/alert";
import { Provider } from "jotai";
import { alertAtom } from "@/app/store/alert/alertAtom";
export default function RootLayout({
children,
params,
}: Readonly<{
children: React.ReactNode;
params: {
alert: string | null;
};
}>) {
const alert =useAtomValue(alertAtom)
return (
<html lang="ko">
<head>
<title>HR Look</title>
</head>
<body className="font-family">
<Provider>
{/*알럿*/}
{alertOpen === "on" && <Alert />}
{children}
</Provider>
</body>
</html>
);
}
nextjs14 규칙으로써 app 루트 내부 layout 파일은 필수적으로 존재해야하며 모든 페이지에서 나타나도록 설정되어있다.
때문에 모든 페이지에 공통적으로 나타나야하거나 적용되야하는 부분이 있다면 위 layout.tsx에서 정의해주면 된다.
그래서 알럿창,모달창을 layout에서 정의하였는데 이를 위해서 모달창 여닫이 여부를 위처럼 전역상태값으로 사용하려했다.
하지만 다른 페이지에서 alertAtom에 대한 값을 변경해줬을 때, 위 layout.tsx에서 해당 전역 상태값이 변경되지 않는 것을 확인할 수 있었다.
확인해보니 next.js 14 공식문서에서 다음과 같이 설명해주고 있었다.
On navigation, layouts preserve state, remain interactive, and do not re-render.
a shared layout is not re-rendered during navigation which could lead to stale searchParams between navigations.
즉, state 값을 감지하지 않아 리렌더링이 되지 않도록 한다는 것이다.
그렇다면 모든 페이지에 공통적으로 나타나야하는 알럿창을 유동적으로 나타내기 위해서 url query string을 활용하기로 했다.
"use client";
import "./globals.css";
import React from "react";
import Alert from "@/app/ui/alert/alert";
import { Provider, useAtomValue } from "jotai";
import { useSearchParams } from "next/navigation";
export default function RootLayout({
children,
params,
}: Readonly<{
children: React.ReactNode;
params: {
alert: string | null;
};
}>) {
const searchParams = useSearchParams();
const alertOpen = searchParams.get("alert");
return (
<html lang="ko">
<head>
<title>HR Look</title>
</head>
<body className="font-family">
<Provider>
{/*알럿*/}
{alertOpen === "on" && <Alert />}
{children}
</Provider>
</body>
</html>
);
}
alert이라는 query string 값이 on일 경우, 알럿을 띄워주도록 설정하여 여닫이 여부 데이터를 quert string으로 전체에서 공유하도록 하였다.