Skip to content

[캠퍼스] 신규 공지사항 표시 hydration mismatch 수정#1105

Merged
ff1451 merged 6 commits intodevelopfrom
fix/#1104/new-article-hydration-mismatch
Jan 26, 2026
Merged

[캠퍼스] 신규 공지사항 표시 hydration mismatch 수정#1105
ff1451 merged 6 commits intodevelopfrom
fix/#1104/new-article-hydration-mismatch

Conversation

@ff1451
Copy link
Contributor

@ff1451 ff1451 commented Jan 6, 2026

What is this PR? 🔍

Changes 📝

image
  • 프로덕션 환경에서 클라이언트와 서버 시간 차이로 새 게시글에 표시되는 이미지의 표시 여부에서 하이드레이션 불일치 문제가 발생
  • 서버에서 새 게시글 여부를 계산 후 내려주도록 수정

Precaution

사용자의 이용에 문제가 되는 버그는 아니라고 생각하여 핫픽스가 아닌 일반 버그 수정으로 올렸습니다.

✔️ Please check if the PR fulfills these requirements

  • It's submitted to the correct branch, not the develop branch unconditionally?
  • If on a hotfix branch, ensure it targets main?
  • There are no warning message when you run yarn lint

@ff1451 ff1451 self-assigned this Jan 6, 2026
@ff1451 ff1451 added the 🐞 BugFix 버그 수정 label Jan 6, 2026
@github-actions github-actions bot requested review from D0Dam and gimadud January 6, 2026 06:50
Copy link
Contributor

@D0Dam D0Dam left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

오랜만에 들렸다 갑니당

next는 type import가 혹시 안되나요?
그런거라면 type prefix 관련 리뷰들은 무시해주세용

Comment on lines +23 to +25
export function isArticleWithNew(article: Article | ArticleWithNew): article is ArticleWithNew {
return 'isNew' in article && typeof (article as ArticleWithNew).isNew === 'boolean';
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

올..

}

export default function ArticleHeader({ boardId, title, registeredAt, author, hit }: ArticleHeaderProps) {
export default function ArticleHeader({ boardId, title, registeredAt, author, hit, isNew }: ArticleHeaderProps) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

isNew인거랑 아닌거랑 무슨 차이가 있나요?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

image

isNew일 경우 게시글 제목 옆에 위 이미지가 추가로 표시됩니다!

import Image from 'next/image';
import Link from 'next/link';
import { Article } from 'api/articles/entity';
import { Article, ArticleWithNew, isArticleWithNew } from 'api/articles/entity';
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
import { Article, ArticleWithNew, isArticleWithNew } from 'api/articles/entity';
import { type Article, type ArticleWithNew, isArticleWithNew } from 'api/articles/entity';

@@ -1,6 +1,7 @@
import { keepPreviousData, useQuery } from '@tanstack/react-query';
import { PaginationInfo } from 'api/articles/entity';
import { ArticleWithNew, PaginationInfo } from 'api/articles/entity';
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
import { ArticleWithNew, PaginationInfo } from 'api/articles/entity';
import type { ArticleWithNew, PaginationInfo } from 'api/articles/entity';

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

오랜만에 타입 import 하다보니... 수정했습니다!
fc2aae1


function setArticleRegisteredDate(time: string) {
const registered = convertDate(time)
export const isNewArticle = (registeredAt: string, currentDate: Date): boolean => {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

리턴값 추론 될 것 같은데... 안되나요?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

자동 추론 돼서 명시해 둔 부분 제거했습니다 감사합니다!
fc2aae1

<span className={styles['list__item-type']}>{convertArticlesTag(article.board_id)}</span>
<span className={styles['list__item-title']}>{article.title}</span>
{setArticleRegisteredDate(article.registered_at) && (
{isArticleWithNew(article) && article.isNew && (
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

무언가 두 개의 성격이 같아 보이는데, 로직 상 어쩌다 이렇게 나오게 되었나요?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

초기에는 ArticleList가 Article 타입을 받을 수 있어 isArticleWithNew type guard가 필요했으나, 이후 useArticles 훅에서 select를 통해 항상 ArticleWithNew를 반환하도록 변경되었습니다. 하지만 기존 type guard를 제거하지 않아 불필요한 중복 체크가 남아있었고, 이번 수정으로 타입 정의와 로직을 정리했습니다.

IndexArticles에서도 위 내용을 그대로 가져다 쓰면서 중복 체크가 되고 있었기에 수정 진행했습니다!

5045bd9

@ff1451 ff1451 requested a review from D0Dam January 6, 2026 12:23
Copy link
Contributor

@dooohun dooohun left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

수고하셨습니다!

@ff1451 ff1451 merged commit 77b9804 into develop Jan 26, 2026
2 checks passed
@github-actions github-actions bot deleted the fix/#1104/new-article-hydration-mismatch branch January 26, 2026 04:57
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

🐞 BugFix 버그 수정

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[캠퍼스] 신규 공지사항 표시 hydration mismatch 수정

3 participants