Skip to content

Commit

Permalink
배포시 서버측 Date값과 클라이언트측 Date값이 달라 Hydrate error가 발생하는 문제 수정
Browse files Browse the repository at this point in the history
 배포시 서버측 Date값과 클라이언트측 Date값이 달라 Hydrate error가 발생하는 문제 수정
  • Loading branch information
seoko97 authored Oct 3, 2023
2 parents 169e7b5 + 5b883b0 commit 24a11f2
Show file tree
Hide file tree
Showing 16 changed files with 106 additions and 68 deletions.
28 changes: 28 additions & 0 deletions .vscode/launch.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
{
"version": "0.2.0",
"configurations": [
{
"name": "Next.js: debug server-side",
"type": "node-terminal",
"request": "launch",
"command": "yarn dev"
},
{
"name": "Next.js: debug client-side",
"type": "chrome",
"request": "launch",
"url": "http://localhost:3000"
},
{
"name": "Next.js: debug full stack",
"type": "node-terminal",
"request": "launch",
"command": "yarn dev",
"serverReadyAction": {
"pattern": "- Local:.+(https?://.+)",
"uriFormat": "%s",
"action": "debugWithChrome"
}
}
]
}
4 changes: 2 additions & 2 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,7 @@ COPY yarn.lock .
COPY .yarnrc.yml .
COPY .pnp.cjs .
COPY .pnp.loader.mjs .
COPY .yarn/releases ./.yarn/releases
COPY .yarn/cache ./.yarn/cache
COPY .yarn .yarn

RUN yarn install

Expand All @@ -35,6 +34,7 @@ COPY --from=builder /app/.pnp.cjs ./.pnp.cjs
COPY --from=builder /app/package.json ./package.json
COPY --from=builder /app/yarn.lock ./yarn.lock
COPY --from=builder /app/.yarnrc.yml ./yarnrc.yml
COPY --from=builder /app/.env ./.env

ENV NODE_ENV production
ENV PORT 3000
Expand Down
3 changes: 1 addition & 2 deletions src/app/layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -77,12 +77,11 @@ const RootLayout = ({ children }: { children: React.ReactNode }) => {

const theme = localStorage.getItem("theme");

const persistedPreference = theme === "undefined" ? null : theme;
const persistedPreference = theme === "dark" || theme === "light" ? theme : null;

const colorMode = persistedPreference || (prefersDarkFromMq ? "dark" : "light");

localStorage.setItem("theme", colorMode);

document.body.dataset.theme = colorMode;
}

Expand Down
4 changes: 0 additions & 4 deletions src/app/tag/[name]/page.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,6 @@ export const generateMetadata = async ({ params }: IProps): Promise<Metadata> =>
const description = `TAG [${name}]에 대한 포스팅 목록`;

const thumbnail = "/SEOKO.png";
const publishedTime = new Date(tag.createdAt).toISOString();
const modifiedTime = new Date(tag.updatedAt || tag.createdAt).toISOString();

return {
title: metadataTitle,
Expand All @@ -35,8 +33,6 @@ export const generateMetadata = async ({ params }: IProps): Promise<Metadata> =>
title: metadataTitle,
description,
images: [{ url: thumbnail }],
publishedTime,
modifiedTime,
},
};
};
Expand Down
6 changes: 1 addition & 5 deletions src/components/Analytics.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,9 @@ const Analytics = () => {

return (
<>
<NextScript
strategy="afterInteractive"
src={`https://www.googletagmanager.com/gtag/js?id=${GA_TRACKING_ID}`}
/>
<NextScript src={`https://www.googletagmanager.com/gtag/js?id=${GA_TRACKING_ID}`} />
<NextScript
id="google-analytics"
strategy="afterInteractive"
dangerouslySetInnerHTML={{
__html: `
window.dataLayer = window.dataLayer || [];
Expand Down
6 changes: 4 additions & 2 deletions src/components/pages/Series/[nid]/page.client.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,12 @@

import React, { useRef, useState } from "react";

import { dateTimeParser } from "@utils/dateTimeParser";
import { useGetUserQuery } from "@hooks/query/user";
import { useDeleteSeriesMutation, useGetSeriesQuery } from "@hooks/query/series";
import { useGetPostsQuery } from "@hooks/query/post";
import PostList from "@components/ui/PostList";
import Navigation from "@components/ui/Navigation";
import DateTime from "@components/ui/core/DateTime";
import EditSeries from "@components/modal/series/edit";
import { ChevronIcon } from "@components/icons";

Expand Down Expand Up @@ -55,7 +55,9 @@ const SeriesClient = ({ nid }: IProps) => {
<div className="ml-1 truncate text-sm text-primary text-slate-500 dark:text-slate-400">
<span className="text-primary transition-[color]">{postCount}개의 포스트</span>
<span className="mx-1">·</span>
<span>마지막 업데이트 {dateTimeParser(updatedAt)}</span>
<span>
마지막 업데이트 <DateTime date={updatedAt} />
</span>
</div>
</div>
<div className="flex w-full flex-col gap-5">
Expand Down
6 changes: 4 additions & 2 deletions src/components/pages/Series/page.client.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@ import React from "react";

import Link from "next/link";

import { dateTimeParser } from "@utils/dateTimeParser";
import { useGetSeriesQueries } from "@hooks/query/series";
import Image from "@components/ui/core/Image";
import DateTime from "@components/ui/core/DateTime";

const Series = () => {
const { data: seriesList } = useGetSeriesQueries();
Expand All @@ -33,7 +33,9 @@ const Series = () => {
{series.postCount}개의 포스트
</span>
<span className="mx-1">·</span>
<span>마지막 업데이트 {dateTimeParser(series.updatedAt)}</span>
<span>
마지막 업데이트 <DateTime date={series.updatedAt} />
</span>
</div>
</div>
</div>
Expand Down
17 changes: 5 additions & 12 deletions src/components/ui/DarkModeButton/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,19 +13,12 @@ const DarkModeButton = () => {

const Icon = mode === "light" ? MoonIcon : SunIcon;

const wrapperProps = {
onClick: onChangeTheme,
className:
"b-0 z-50 flex cursor-pointer items-center justify-center border-0 bg-transparent p-0",
};

const iconProps = {
className: "h-6 w-6 fill-gray-500 transition-colors hover:fill-yellow-400",
};

return (
<button {...wrapperProps}>
<Icon {...iconProps} />
<button
onClick={onChangeTheme}
className="b-0 z-50 flex cursor-pointer items-center justify-center border-0 bg-transparent p-0"
>
<Icon className="h-6 w-6 fill-gray-500 transition-colors hover:fill-yellow-400" />
</button>
);
};
Expand Down
2 changes: 0 additions & 2 deletions src/components/ui/Header/Nav.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
"use client";

import React from "react";

import { useGetUserQuery } from "@hooks/query/user";
Expand Down
8 changes: 1 addition & 7 deletions src/components/ui/client/home/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,16 +16,10 @@ const HomeClient = ({ params }: IProps) => {

const [posts, fetchMorePosts] = useGetPostsQuery(params);

const postListProps = {
ref,
posts,
func: fetchMorePosts,
};

return (
<section className="flex w-full flex-col gap-5">
<ContentHeader />
{posts.length > 0 && <PostList {...postListProps} />}
{posts.length > 0 && <PostList ref={ref} posts={posts} func={fetchMorePosts} />}
{posts?.length === 0 && (
<div className="py-10 text-center text-2xl font-bold text-gray-400 sm:text-xl">
포스트를 찾을 수 없습니다 🙄
Expand Down
6 changes: 2 additions & 4 deletions src/components/ui/client/post/PostHeader/PostSubInfo.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import React from "react";

import { dateTimeParser } from "@utils/dateTimeParser";
import DateTime from "@components/ui/core/DateTime";
import { LikeIcon, ViewIcon } from "@components/icons";

interface IProps {
Expand All @@ -12,9 +12,7 @@ interface IProps {
const PostSubInfo = ({ viewCount, likeCount, createdAt }: IProps) => {
return (
<div className="flex flex-wrap items-center justify-start gap-4 text-sm">
<span className="font-normal text-slate-500 dark:text-slate-400">
{dateTimeParser(createdAt)}
</span>
<DateTime className="font-normal text-slate-500 dark:text-slate-400" date={createdAt} />
<div className="flex items-center justify-center gap-1">
<ViewIcon className="h-[1.2em] w-[1.2em] stroke-slate-500 dark:stroke-slate-400" />
<span className="text-slate-500 dark:text-slate-400">{viewCount}</span>
Expand Down
24 changes: 9 additions & 15 deletions src/components/ui/core/Avatar/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,22 +12,16 @@ interface IProps {
const Avatar: React.FC<IProps> = (props) => {
const { src = "/main.jpg", width = 30, height = 30, onClick } = props;

const containerProps = {
onClick,
};

const imageProps = {
width,
height,
src,
quality: 100,
alt: "avatar",
className: "object-cover rounded-[50%]",
};

return (
<div {...containerProps}>
<Image {...imageProps} />
<div onClick={onClick}>
<Image
width={width}
height={height}
src={src}
quality={100}
alt="avatar"
className="rounded-[50%] object-cover"
/>
</div>
);
};
Expand Down
26 changes: 26 additions & 0 deletions src/components/ui/core/DateTime/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import React, { useEffect, useState } from "react";

import { dateTimeParser } from "@utils/dateTimeParser";

interface IProps {
date: string;
className?: string;
}

const DateTime = ({ date, className }: IProps) => {
const [formattedDate, setFormattedDate] = useState<string | null>(null);

useEffect(() => {
const formatted = dateTimeParser(date);

setFormattedDate(formatted);
}, []);

if (!formattedDate) {
return <span className="h-4 w-16 rounded-md bg-slate-300 dark:bg-slate-600" />;
}

return <span className={className}>{formattedDate}</span>;
};

export default DateTime;
6 changes: 5 additions & 1 deletion src/hooks/useDarkMode.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,11 @@ const useDarkMode: TResult = () => {
const [mode, setMode] = useLocalStorage<TDarkMode | undefined>("theme");

useEffect(() => {
setMode(document.body.dataset.theme as TDarkMode);
const theme = (document.body.dataset.theme ||
localStorage.getItem("theme") ||
"light") as TDarkMode;

setMode(theme);
}, []);

useEffect(() => {
Expand Down
26 changes: 17 additions & 9 deletions src/utils/dateTimeParser.ts
Original file line number Diff line number Diff line change
@@ -1,16 +1,24 @@
type Props = (date: string) => string;

export const dateTimeParser: Props = (date) => {
const diff = Math.ceil((new Date().getTime() - new Date(date).getTime()) / (1000 * 60 * 60));
const currentDate = new Date();
const inputDate = new Date(date);

const dateTimeFormat = new Intl.DateTimeFormat("ko", { dateStyle: "long" }).format(
new Date(date),
);
const timeDifference = currentDate.getTime() - inputDate.getTime();
const seconds = Math.floor(timeDifference / 1000);
const minutes = Math.ceil(seconds / 60);
const hours = Math.floor(minutes / 60);
const days = Math.floor(hours / 24);

const relativeTimeFormat = new Intl.RelativeTimeFormat("ko", { numeric: "auto" }).format(
diff * -1,
"hour",
);
if (days >= 1) {
const year = inputDate.getFullYear();
const month = inputDate.getMonth() + 1;
const day = inputDate.getDate();

return diff >= 24 ? dateTimeFormat : relativeTimeFormat;
return `${year}${month}${day}일`;
}

if (hours >= 1) return `${hours}시간 전`;

return `${minutes}분 전`;
};
2 changes: 1 addition & 1 deletion tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,6 @@
"@/*": ["./src/*"]
}
},
"include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".nn/types/**/*.ts", ".next/types/**/*.ts"],
"include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts"],
"exclude": ["node_modules"]
}

0 comments on commit 24a11f2

Please sign in to comment.