Conversation
SangHyun01
approved these changes
Nov 19, 2025
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Ⅰ. 개요
본 PR은 사용자가 질문 노드를 삭제하거나 수정할 때 발생하는 핵심적인 버그들을 해결하고, 전반적인 사용자 경험(UX)을 ChatGPT와 유사한 직관적인 방식으로 대폭 개선하는 것을 목표로 합니다.
주요 변경 사항은 다음과 같습니다.
Ⅱ. 핵심 변경 사항 상세 설명
1. 질문 삭제: 상태 불일치 버그 해결 및 낙관적 업데이트 로직 완성
가. 문제점 (The Bug)
handleDeleteQuestion함수 내에서 전체 트리 데이터인viewData상태는 자식 노드를 올바르게 승계하여 즉시 업데이트되었습니다.currentPath상태는 변경 전의 오래된(stale) 경로 정보를 기반으로 업데이트(currentPath.slice(0, -1))되고 있었습니다.viewData는 최신인데currentPath는 과거인 상태가 되어,currentPath로부터 파생되는currentQuestion이 오래된 자식 목록(children)을 계속 참조하게 되었습니다. 카드 뷰는 바로 이currentQuestion.children을 기반으로 렌더링되므로, 업데이트가 누락된 것입니다.나. 해결 과정 (The Fix)
핵심 해결책:
viewData와currentPath두 상태가 항상 새로운 데이터를 기반으로 함께, 원자적으로(atomically) 업데이트되도록 로직을 전면 수정했습니다.개선된 로직 (
handleDeleteQuestion):JSON.parse(JSON.stringify(viewData))를 통해 현재 트리의 완전한 복사본(newViewData)을 생성하여, 원본 상태를 건드리지 않고 안전하게 조작하도록 보장했습니다.parentPath)를 언제나 새로운 트리 데이터(newViewData)에서findPathToNode유틸 함수를 통해 찾도록 하여, 항상 최신 경로를 참조하게 했습니다.children배열에서 삭제할 노드를 제거하고, 삭제된 노드의 자식들을 그 자리에 추가합니다. (Array.prototype.splice활용)newCurrentPath를 이전처럼slice하는 대신, 새로운 트리에서 찾은parentPath로 설정하여 데이터 정합성을 맞췄습니다.newCurrentPath를 새로운 트리(newViewData)에서findPathToNode를 다시 호출하여 경로 정보를 최신으로 동기화했습니다.setViewData(newViewData)와setCurrentPath(newCurrentPath)를 연속으로 호출하여 두 상태의 불일치 가능성을 원천적으로 차단했습니다.originalViewData,originalCurrentPath)로 완벽하게 되돌리는 롤백 로직을 유지했습니다.2. 질문 수정: 직관적인 인라인(In-line) 방식으로 전면 개편
가. 기존 방식의 문제점 (As-Is)
나. 개선된 방식 (To-Be: ChatGPT-Style Editing)
핵심 개선: 사용자가 '수정' 버튼을 누르면, 보고 있던 질문 텍스트가 그 자리에서 바로 입력창(
Textarea)으로 전환되는, ChatGPT나 Gemini와 같은 매우 직관적인 방식으로 UX를 개편했습니다.구현 상세 (
message-bubble.tsx):EditQuestionDialog.tsx파일을 완전히 삭제하고,use-question-tree.ts와index.tsx에서 모달 관련 상태와 함수를 모두 제거하여 코드를 단순화하고 유지보수성을 높였습니다.isEditing이라는 내부 상태를 사용하여,true일 때는<Textarea>컴포넌트를,false일 때는<div>태그를 렌더링하도록 삼항 연산자로 구현했습니다.Textarea의value를editText상태와 바인딩했습니다.editText는questionTextprop으로 초기화되며,useEffect훅을 통해questionText가 변경될 때마다editText도 함께 업데이트됩니다. 이것이 브레드크럼 이동 시에도 항상 최신 질문 내용이Textarea에 채워지도록 보장하는 핵심 로직입니다.OptimisticAnswer) 영역은isEditing상태와 관계없이 항상 표시되도록 JSX 구조를 수정했습니다.isEditing상태일 때만Textarea하단에 '수정 완료'와 '취소' 버튼이 나타나도록 구현했습니다.Ⅲ. 기타 개선 사항
sonner라이브러리를 활용하여, 사용자가 '삭제' 버튼 클릭 시 "정말 삭제하시겠습니까?" 라는 확인 토스트(Toast)를 띄워 의도치 않은 데이터 삭제를 방지하는 안전장치를 마련했습니다.이러한 변경들을 통해 애플리케이션의 핵심 기능인 질문 관리의 안정성과 사용성을 크게 향상시켰습니다.