Skip to content

[fix] styled 컴포넌트의 스타일용 prop이 DOM 속성으로 새지 않게 transient prop으로 바꾼다 - #2249

Merged
seongwon030 merged 2 commits into
develop-fefrom
fix/#2248-styled-transient-props-MOA-1225
Oct 25, 2026
Merged

seongwon030 merged 2 commits into
develop-fefrom
fix/#2248-styled-transient-props-MOA-1225

Conversation

@seongwon030

@seongwon030 seongwon030 commented Oct 25, 2026 •

Copy link
Copy Markdown
Member

Close #2248
Close #2247

문제

styled-components v6는 DOM 대상 styled 컴포넌트에 들어온 $ 없는 prop을 거르지 않고 DOM 속성으로 넘긴다. 스타일 분기용 prop(isScrolled, active, hasError …)이 그대로 새어 개발 콘솔에 React prop 경고가 쌓이고, IntroSection의 Shape처럼 객체 prop은 laptop="[object Object]"로 박혔다. 사용자에게 보이는 깨짐은 없지만 진짜 경고가 묻힌다.

해결

스타일 분기에만 쓰는 prop을 transient prop($)으로 바꾸고 호출부를 맞췄다. 이미 10개 파일이 쓰는 $active 방식을 따랐다. 이슈 표에 없던 SelectTags의 Button(selected·color)도 같은 문제라 함께 고쳤다.

  • 실제 HTML 속성으로 넘기는 Input의 readOnly, Arrow(img)의 width·height, th의 width는 그대로 둔다.
  • 감싸는 컴포넌트(InputField, CustomTextArea, QuestionContainer)의 공개 prop 이름은 바꾸지 않는다.

검증

develop-fe와 이 브랜치를 Playwright로 나란히 띄워 대조했다.

화면 React prop 경고 누출 속성
/ · /introduce · /peace 3·1·1 → 0 160·72·0 → 0
지원서 편집 · 지원자 목록 · 동아리 정보 2·4·2 → 0 8·9·13 → 0
  • 관리자 화면은 테스트 계정으로 로그인해 토글·드롭다운·체크박스 상태까지 확인했다. 바꾼 컴포넌트의 계산된 스타일 573건이 전후 동일했다.
  • 소개 페이지 배경 도형 위치는 1440·1024·768·390에서 일치했다.
  • tsc 통과, jest 102 suites / 777 tests 통과
  • 확인 못 한 것: InputField·CustomTextArea의 에러/성공 상태, 지원서 작성 QuestionContainer 에러, PhotoModal, DdayBadge, Popup. 이 컴포넌트들은 코드와 타입으로만 확인했다.

영향 범위

학생용(헤더, 메인 배너·팝업, 소개, 상세 사진 모달, 지원서 작성)과 관리자용(지원서 편집, 지원자 목록, 동아리 정보)에 닿는다. 앱 웹뷰도 같은 화면을 쓴다. prop 이름만 바뀌고 스타일 값은 같다. 백엔드·앱 배포 순서 제약은 없다.

한계와 대안(선택)

앱 루트에 StyleSheetManager shouldForwardProp를 두는 방법은 고르지 않았다. 한 번에 막히지만 잘못 쓴 prop이 조용히 숨고, is-prop-valid가 모르는 커스텀 속성까지 걸러질 수 있다.

Summary by CodeRabbit

  • 개선 사항
    • 입력창, 배너, 팝업, 관리자 화면 등 여러 영역의 표시와 상호작용은 기존과 동일하게 유지됩니다.
    • 화면 스타일에 사용되는 내부 속성 전달 방식이 정리되어, 브라우저에 불필요한 속성이 전달되지 않도록 개선했습니다.

styled-components v6는 DOM 대상 styled 컴포넌트에서 $ 없는 prop을 거르지
않고 그대로 DOM 속성으로 넘긴다(v5의 is-prop-valid 기본 필터가 없다).
그래서 isScrolled·active·hasError 같은 스타일 분기용 prop이 React prop
경고를 내고, Shape의 laptop처럼 객체 prop은 "[object Object]" 속성으로
박혔다.

스타일 분기에만 쓰는 prop을 $ prop으로 바꾸고 호출부를 맞춘다. 실제 HTML
속성으로 넘기는 Input readOnly, Arrow(img) width/height, th width는 그대로
둔다. 감싸는 컴포넌트의 공개 prop 이름은 바꾸지 않는다.
@vercel

vercel Bot commented Oct 25, 2026 •

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated
moadong Ready Ready Preview Oct 25, 2026 11:23am UTC

@seongwon030 seongwon030 self-assigned this Oct 25, 2026
@github-actions github-actions Bot added the 💻 FE Frontend label Oct 25, 2026
@reviewer-harry

reviewer-harry Bot commented Oct 25, 2026 •

Copy link
Copy Markdown

Claude finished @seongwon030's task in 1m 23s —— View job


harry 리뷰 총평

  • 리뷰 기준(.github/harry-review-rules.md) 읽기
  • origin/develop-fe 대비 diff 전체 보기 (26개 파일)
  • 바꾼 styled 컴포넌트를 다른 곳에서 쓰는지 확인
  • 인라인 코멘트 남기기

범위를 잘 지켰어요. 스타일에만 쓰는 prop을 $로 바꾸는 일만 했고, 실제 HTML 속성(readOnly, img의 width·height, th의 width)과 감싸는 컴포넌트의 공개 prop 이름은 그대로 뒀어요. 기존 $active 방식과도 맞아요.

확인한 것

  • 바꾼 *.styles.ts를 import하는 곳을 찾아봤어요. 이 PR이 고친 파일 말고는 HEADER_HEIGHT만 가져다 쓰고, AdminProfile.tsx도 Styled.Header는 안 써요. 그래서 이름을 바꿨는데 다른 호출부가 옛 이름을 계속 넘기는 경우는 찾지 못했어요.
  • IntroSection은 SHAPES의 키를 {...pos}로 펼쳐서 넘겨요. 키 이름을 같이 바꿔서 위치 값은 그대로 이어져요.
  • ApplicantsTab의 DeleteButton(img)은 원래 disabled가 HTML에서 아무 동작도 안 하던 속성이라, $disabled로 바꿔도 클릭 동작은 달라지지 않아요.

인라인 코멘트 2건 (둘 다 가벼운 제안이에요)

  • Popup.styles.ts: ModalContainer가 $isOpen을 선언만 하고 스타일에서 안 읽어요. 지우는 게 나아요.
  • IntroSection.tsx: 데이터 상수 SHAPES의 키에까지 $가 들어갔어요. 렌더할 때 이어 주는 방식을 제안했어요.

참고

  • 하드코딩된 색(#ff5000, #E6F4FB 등)이 바뀐 줄에 보이지만, 원래 있던 값의 prop 이름만 바뀐 거라 이번 리뷰에서는 지적하지 않았어요.
  • 이 리뷰 실행에서는 tsc와 jest를 돌리지 않았어요(명령 승인이 안 됐어요). PR 본문에 적힌 통과 결과를 기준으로 봤어요.

@diboreview-e2e-bot diboreview-e2e-bot Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

켜진 규칙 위반이 없어요.

지적 0개 · 버린 지적 0개 · 중복 제외 0개 · 비용 $0.0707

@coderabbitai

coderabbitai Bot commented Oct 25, 2026 •

Copy link
Copy Markdown
Contributor

Review in Change Stack →

Warning

Review limit reached

You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository.

Next included review available in 56 minutes.

Check out review usage here.

View limit details

Limit details: You’ve used the included review currently available.

Learn how review limits work.

Review configuration:

Run configuration
Commits

Reviewing files that changed from the base of the PR and between de7ec5e and af5d49f.

Files selected for processing: 2
  • frontend/src/pages/MainPage/components/Popup/Popup.styles.ts
  • frontend/src/pages/MainPage/components/Popup/Popup.tsx

No actionable comments were generated in the recent review.

Recent review info
Run configuration
Commits

Reviewing files that changed from the base of the PR and between 548bfdb and de7ec5e.

Files selected for processing: 26
  • frontend/src/components/ClubTag/ClubTag.tsx
  • frontend/src/components/common/CustomTextArea/CustomTextArea.styles.ts
  • frontend/src/components/common/CustomTextArea/CustomTextArea.tsx
  • frontend/src/components/common/Header/Header.styles.ts
  • frontend/src/components/common/Header/Header.tsx
  • frontend/src/components/common/InputField/InputField.styles.ts
  • frontend/src/components/common/InputField/InputField.tsx
  • frontend/src/components/promotion/PromotionCardView/DdayBadge/DdayBadge.styles.ts
  • frontend/src/components/promotion/PromotionCardView/DdayBadge/DdayBadge.tsx
  • frontend/src/pages/AdminPage/components/QuestionBuilder/QuestionBuilder.styles.ts
  • frontend/src/pages/AdminPage/components/QuestionBuilder/QuestionBuilder.tsx
  • frontend/src/pages/AdminPage/tabs/ApplicantsTab/ApplicantsTab.styles.ts
  • frontend/src/pages/AdminPage/tabs/ApplicantsTab/ApplicantsTab.tsx
  • frontend/src/pages/AdminPage/tabs/ClubInfoEditTab/components/desktop/SelectTags/SelectTags.styles.ts
  • frontend/src/pages/AdminPage/tabs/ClubInfoEditTab/components/desktop/SelectTags/SelectTags.tsx
  • frontend/src/pages/ApplicationFormPage/components/QuestionContainer/QuestionContainer.tsx
  • frontend/src/pages/ClubDetailPage/components/PhotoModal/PhotoModal.styles.ts
  • frontend/src/pages/ClubDetailPage/components/PhotoModal/PhotoModal.tsx
  • frontend/src/pages/IntroducePage/components/sections/1.IntroSection/IntroSection.styles.ts
  • frontend/src/pages/IntroducePage/components/sections/1.IntroSection/IntroSection.tsx
  • frontend/src/pages/IntroducePage/components/sections/7.ContactSection/ContactSection.styles.ts
  • frontend/src/pages/IntroducePage/components/sections/7.ContactSection/ContactSection.tsx
  • frontend/src/pages/MainPage/components/Banner/Banner.styles.ts
  • frontend/src/pages/MainPage/components/Banner/Banner.tsx
  • frontend/src/pages/MainPage/components/Popup/Popup.styles.ts
  • frontend/src/pages/MainPage/components/Popup/Popup.tsx

Included review availability: This review used your included allowance. Your plan provides up to 1 included review per hour; 0 remain after this review.

Walkthrough

스타일 전용 prop을 styled-components transient prop인 $ 접두사 형태로 변경했습니다. 관련 스타일 선언과 호출부를 함께 수정했으며, 요약된 변경 내용에서는 기존 스타일 조건과 렌더링 동작을 유지합니다.

Changes

스타일 전용 prop 변경

Layer / File(s) Summary
공통 컴포넌트 스타일 prop
frontend/src/components/ClubTag/ClubTag.tsx, frontend/src/components/common/CustomTextArea/*, frontend/src/components/common/Header/*, frontend/src/components/common/InputField/*, frontend/src/components/promotion/PromotionCardView/DdayBadge/*
태그 색상, 입력 너비·오류 상태, 헤더 스크롤 상태, 입력 오류·성공 상태, D-day 종료 상태 prop을 $ 접두사 형태로 변경했습니다. 스타일 조건과 색상 선택은 유지됩니다.
관리자 화면 스타일 prop
frontend/src/pages/AdminPage/components/QuestionBuilder/*, frontend/src/pages/AdminPage/tabs/ApplicantsTab/*, frontend/src/pages/AdminPage/tabs/ClubInfoEditTab/components/desktop/SelectTags/*
질문 빌더의 활성·열림·읽기 전용 상태, 지원자 탭의 배경색·비활성·표시 상태, 태그 선택 버튼의 선택·색상 prop을 $ 접두사 형태로 변경했습니다.
신청 폼과 사진 모달
frontend/src/pages/ApplicationFormPage/components/QuestionContainer/QuestionContainer.tsx, frontend/src/pages/ClubDetailPage/components/PhotoModal/*
질문 컨테이너의 오류 상태와 사진 모달의 버튼 위치·썸네일 활성 상태 prop을 $ 접두사 형태로 변경했습니다.
소개 및 메인 화면 스타일 prop
frontend/src/pages/IntroducePage/components/sections/1.IntroSection/*, frontend/src/pages/IntroducePage/components/sections/7.ContactSection/*, frontend/src/pages/MainPage/components/Banner/*, frontend/src/pages/MainPage/components/Popup/*
소개 페이지 도형 위치와 메인 배너·팝업 상태 prop을 $ 접두사 형태로 변경했습니다. 위치값과 상태별 스타일 조건은 유지됩니다.

Priority: Pending latest changes

Estimated code review effort: 2 (Simple) | ~12 minutes

Change: Bug fix · Severity of issue fixed: Low

Suggested labels: 💻 FE

Suggested reviewers: oesnuj

Merge Risk: Minimal · up to de7ec

No confirmed issue prevents merging after normal checks.

Pre-merge checks: Passed 5
Check name Status Explanation
Description Check Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check Passed 제목은 styled-components의 스타일 전용 prop을 transient prop으로 변경하여 DOM 속성 누출을 방지하는 PR의 주요 변경 사항을 정확히 요약합니다.
Linked Issues check Passed [#2247, #2248] 두 이슈의 코딩 요구사항은 같은 내용입니다. 스타일 분기용 $ 없는 prop을 transient prop($)으로 바꾸고 호출부를 맞추는 작업입니다. 변경 요약 기준으로 대상 목록의 항목은 모두 변경되었습니다.
- Header: isScrolled → $isScrolled
- ClubTag StyledTag: `…
Out of Scope Changes check Passed 모든 변경은 #2247·#2248의 대상 목록 또는 명시된 제외 항목과 연결됩니다. 대상 목록에 없는 변경은 SelectTags.styles.ts의 Button(selected·color → $selected·$color)과 그 호출부 SelectTags.tsx입니다. 이 변경은 DOM 대상 styled 컴포넌트에 $ 없는 스타…
Docstring Coverage Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check. Docstring coverage is scoped to functions touched by this diff. Analyzed 0 functions across 2…
Full details: Linked Issues check

Explanation

[#2247, #2248] 두 이슈의 코딩 요구사항은 같은 내용입니다. 스타일 분기용 $ 없는 prop을 transient prop($)으로 바꾸고 호출부를 맞추는 작업입니다. 변경 요약 기준으로 대상 목록의 항목은 모두 변경되었습니다.

  • Header: isScrolled → $isScrolled
  • ClubTag StyledTag: color → $color
  • CustomTextArea: TextAreaContainer width → $width, TextArea hasError → $hasError
  • InputField: InputContainer width, Input hasError·isSuccess, HelperText isError를 $ 접두사로 변경
  • DdayBadge DdayText: isEnded → $isEnded
  • QuestionBuilder: active, open, readOnly를 $active, $open, $readOnly로 변경
  • ApplicantsTab: SummaryCard bgColor, StatusSelect disabled, DeleteButton disabled, ApplicantTableHeader borderLeft·isMemo, ApplicantTableCol isMemo, ApplicantStatusBadge status를 $ 접두사로 변경
  • QuestionContainer Container: hasError → $hasError
  • PhotoModal: NavButton position, Thumbnail isActive를 $position, $isActive로 변경
  • IntroSection Shape 7개 prop, ContactSection Shape 4개 prop을 $ 접두사로 변경
  • Banner: BannerItem isClickable, Dot active를 $ 접두사로 변경
  • Popup: Overlay, ModalContainer의 isOpen을 $isOpen으로 변경

실제 HTML 속성은 요구대로 유지되었습니다: Input readOnly, Arrow(img) width·height, ApplicantTableHeader(th) width. 감싸는 컴포넌트(InputField, CustomTextArea, QuestionContainer)의 공개 prop 이름도 유지되었습니다.

HEAD 소스 확인: ApplicantsTab.styles.ts의 선언과 ApplicantsTab.tsx의 호출부(SummaryCard $bgColor, StatusSelect $disabled, DeleteButton $disabled, Arrow width/height 유지)가 일치합니다. 나머지 파일은 변경 요약과 PR 설명을 근거로 판단했습니다.

테스트: 변경 요약에는 테스트 파일 변경이 없습니다. PR은 jest 102 suites / 777 tests 통과와 tsc 통과를 보고합니다. 호출부 테스트의 prop 이름 갱신 요구는 충족된 것으로 봅니다.

Playwright 콘솔 경고 0건 확인은 검증 절차입니다. 비코딩 항목이므로 판정 기준에서 제외했습니다.

Full details: Out of Scope Changes check

Explanation

모든 변경은 #2247·#2248의 대상 목록 또는 명시된 제외 항목과 연결됩니다. 대상 목록에 없는 변경은 SelectTags.styles.ts의 Button(selected·color → $selected·$color)과 그 호출부 SelectTags.tsx입니다. 이 변경은 DOM 대상 styled 컴포넌트에 $ 없는 스타일 prop을 넘기는 같은 문제입니다. 이슈 제목의 일반 범위에 속하고 PR 설명에서 명시적으로 밝혔습니다. 따라서 범위를 벗어난 변경으로 보지 않습니다.

나머지 변경은 다음 중 하나입니다.

  • 대상 prop의 선언과 호출부 갱신(예: IntroSection.tsx의 SHAPES 설정 키 변경, Banner.tsx, Popup.tsx, ApplicantsTab.tsx의 $ 전달)
  • 명시된 제외 항목 유지(Input readOnly, Arrow width·height, th width)

관련 없는 기능 변경, 리팩터링, 문서 변경은 변경 요약에서 발견되지 않았습니다.

Full details: Docstring Coverage

Explanation

No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check. Docstring coverage is scoped to functions touched by this diff. Analyzed 0 functions across 26 files.

Finishing Touches
📝 Generate docstrings
  • Commit to this branch
  • Create a new PR
🧪 Generate unit tests (beta)
  • Commit to this branch
  • Create a new PR
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@github-actions

github-actions Bot commented Oct 25, 2026 •

Copy link
Copy Markdown

🎨 UI 변경사항을 확인해주세요

변경된 스토리를 Chromatic에서 확인해주세요.

구분 링크
🔍 변경사항 리뷰 https://www.chromatic.com/build?appId=67904e61c16daa99a63b44a7&number=1262
📖 Storybook https://67904e61c16daa99a63b44a7-hayqobbrvx.chromatic.com/

9개 스토리 변경 · 전체 191개 스토리 · 67개 컴포넌트

@seongwon030
seongwon030 merged commit 9ed50c8 into develop-fe Oct 25, 2026
16 checks passed
@seongwon030
seongwon030 deleted the fix/#2248-styled-transient-props-MOA-1225 branch October 25, 2026 11:53

This branch was successfully deployed

1 active deployment
Preview — af5d49f6 Deployed Oct 25, 2026 by vercel[bot]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

💻 FE Frontend

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant