[FIX] Today 카드 서브태스크 완료가 상세 모달에 재동기화되지 않는 문제 수정#256
Conversation
- Today 카드에서 서브태스크를 완료 토글한 직후 상세 모달을 열면, 모달의 첫 조회가 완료 처리 요청보다 먼저 끝나 옛 데이터로 폼이 초기화되는 문제가 있었습니다 - useDetailSubtaskField의 subtaskInputs가 마운트 시 한 번만 초기화되고 이후 재동기화되지 않아, 서버 데이터가 나중에 갱신되어도 체크박스가 계속 옛 값에 머물렀습니다 - 서버에서 받아온 subtasks가 바뀔 때 완료 여부만 로컬 폼 상태에 재동기화하는 effect를 추가했습니다
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
|
Warning Review limit reached
Next review available in: 38 minutes Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available. How can I continue?After more reviews become available, a review can be triggered using the To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews. How do review limits work?CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability. For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window. Please refer docs for additional details. Review details⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: ASSERTIVE Plan: Pro Plus Run ID: 📒 Files selected for processing (1)
Walkthrough
Changes서브태스크 상태 동기화
Estimated code review effort: 2 (Simple) | ~10 minutes Possibly related PRs
Suggested reviewers: 🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
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. Comment |
Timo Performance ReportBundle Size — timo-web
Lighthouse — timo-web
Image Optimization — timo-web
측정 커밋: |
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@apps/timo-web/hooks/todo-modal/detail/use-detail-subtask-field.ts`:
- Around line 43-56: Update the state updater in the useEffect synchronization
for subtasks to track whether any completed value changes; return the original
prev reference when no matching subtask requires an update, and only return a
new mapped array when at least one value changes.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: ASSERTIVE
Plan: Pro Plus
Run ID: 0fd604c3-0e5d-4f95-917f-3a9a5f1d318d
📒 Files selected for processing (1)
apps/timo-web/hooks/todo-modal/detail/use-detail-subtask-field.ts
| useEffect(() => { | ||
| setSubtaskInputs((prev) => | ||
| prev.map((input) => { | ||
| const serverSubtask = subtasks.find( | ||
| (subtask) => subtask.subtaskId === input.subtaskId, | ||
| ); | ||
| if (!serverSubtask || serverSubtask.completed === input.completed) { | ||
| return input; | ||
| } | ||
| return { ...input, completed: serverSubtask.completed }; | ||
| }), | ||
| ); | ||
| }, [subtasks]); | ||
|
|
There was a problem hiding this comment.
🚀 Performance & Scalability | 🔵 Trivial | ⚡ Quick win
불필요한 재렌더링을 방지하도록 상태 업데이트 로직 개선
서브태스크 동기화 로직, 필요한 부분만 잘 캐치해서 작성해주셨네요! 센스 최고예요! 👏
현재 prev.map을 사용하면 실제 completed 값이 변경되지 않았더라도 항상 새로운 배열이 생성되어 반환됩니다. 이로 인해 subtasks 배열의 참조가 바뀔 때마다 상태가 업데이트되어 불필요한 재렌더링이 발생할 수 있습니다.
상태를 업데이트할 때 실제 변경 사항이 있는지를 추적하여, 변경이 없을 경우에는 이전 상태(prev)의 참조를 그대로 반환하도록 개선하면 React가 렌더링을 건너뛰게 할 수 있습니다.
관련해서는 React 공식 문서: State 업데이트 건너뛰기를 참고해 보시면 더 깊이 이해하는 데 도움이 될 거예요!
💡 재렌더링 방지를 위한 개선 제안
useEffect(() => {
- setSubtaskInputs((prev) =>
- prev.map((input) => {
+ setSubtaskInputs((prev) => {
+ let hasChanges = false;
+ const next = prev.map((input) => {
const serverSubtask = subtasks.find(
(subtask) => subtask.subtaskId === input.subtaskId,
);
if (!serverSubtask || serverSubtask.completed === input.completed) {
return input;
}
+ hasChanges = true;
return { ...input, completed: serverSubtask.completed };
- }),
- );
+ });
+ return hasChanges ? next : prev;
+ });
}, [subtasks]);📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| useEffect(() => { | |
| setSubtaskInputs((prev) => | |
| prev.map((input) => { | |
| const serverSubtask = subtasks.find( | |
| (subtask) => subtask.subtaskId === input.subtaskId, | |
| ); | |
| if (!serverSubtask || serverSubtask.completed === input.completed) { | |
| return input; | |
| } | |
| return { ...input, completed: serverSubtask.completed }; | |
| }), | |
| ); | |
| }, [subtasks]); | |
| useEffect(() => { | |
| setSubtaskInputs((prev) => { | |
| let hasChanges = false; | |
| const next = prev.map((input) => { | |
| const serverSubtask = subtasks.find( | |
| (subtask) => subtask.subtaskId === input.subtaskId, | |
| ); | |
| if (!serverSubtask || serverSubtask.completed === input.completed) { | |
| return input; | |
| } | |
| hasChanges = true; | |
| return { ...input, completed: serverSubtask.completed }; | |
| }); | |
| return hasChanges ? next : prev; | |
| }); | |
| }, [subtasks]); |
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@apps/timo-web/hooks/todo-modal/detail/use-detail-subtask-field.ts` around
lines 43 - 56, Update the state updater in the useEffect synchronization for
subtasks to track whether any completed value changes; return the original prev
reference when no matching subtask requires an update, and only return a new
mapped array when at least one value changes.
ehye1
left a comment
There was a problem hiding this comment.
굿굿 subtask가 업데이트가 안되고 있었군요
오류 수정 감사합니다!!
- 체크박스가 checked 상태일 때만 렌더링되는 체크마크 아이콘이 SVGElement라서 HTMLElement의 인스턴스가 아니었습니다 - isInteractiveElement가 target instanceof HTMLElement로 검사해, 체크 해제를 위해 체크마크를 직접 클릭하면 인터랙티브 요소로 인식하지 못하고 카드 클릭(상세 모달 오픈)으로 새어나갔습니다 - instanceof Element로 변경해 HTML/SVG 요소 모두 정상적으로 감지하도록 했습니다
jjangminii
left a comment
There was a problem hiding this comment.
서브테스크 오늘/홈/수정모달/포커스 각각 동기화 되는 것 확인 했습니다.
ISSUE 🔗
close #255
What is this PR? 🔍
Today 카드에서 서브태스크 완료를 토글한 직후 상세 조회 모달을 열면 완료 상태가 반영되지 않던 문제를 수정했습니다.
배경
useDetailSubtaskField의subtaskInputs는 모달 마운트 시useStatelazy initializer로 서버subtasks를 한 번만 읽어와 초기화하고, 이후에는 자체 로컬 상태로만 관리됩니다.todo.subtasks는 최신값으로 바뀌지만, 이미 초기화된 로컬subtaskInputs는 재동기화 로직이 없어 계속 옛 값(미완료)에 머물렀습니다.subtasks가 바뀔 때, 로컬 폼 상태의 완료 여부만 최신값으로 재동기화하는 effect를 추가했습니다.서브태스크 완료 동기화
useDetailSubtaskField에subtasksprop 변경을 감지해subtaskInputs의completed값만 재동기화하는useEffect를 추가했습니다.subtasks배열이 바뀔 때마다subtaskId로 매칭되는 서버 서브태스크를 찾아completed값이 다르면 해당 항목만 갱신합니다. 텍스트(value)와 아직 저장되지 않은 로컬 입력행(subtaskId: null)은 건드리지 않아, 사용자가 입력 중인 텍스트가 덮어써지지 않도록 했습니다.To Reviewers
로컬 폼 상태(
subtaskInputs)와 서버 쿼리 데이터(todo.subtasks) 사이의 재동기화 시점이 올바른지, 특히 사용자가 서브태스크 텍스트를 편집 중인 상태에서completed만 갱신되는 게 의도대로 동작하는지 확인 부탁드립니다.Screenshot 📷
Test Checklist ✔
pnpm check-types통과pnpm lint통과pnpm build— 미실행: CI에서 확인 예정