Skip to content

[widgets] PR 리뷰 기반 UI 동작 보정#34

Merged
tlrdmsEjrqhRdl merged 1 commit into
developfrom
fix/ui
Jul 3, 2026
Merged

[widgets] PR 리뷰 기반 UI 동작 보정#34
tlrdmsEjrqhRdl merged 1 commit into
developfrom
fix/ui

Conversation

@tlrdmsEjrqhRdl

Copy link
Copy Markdown
Contributor

아까 실수로 comment 올라온 것들이 push가 되지 않아 다시 업로드 합니다

@vercel

vercel Bot commented Jul 3, 2026

Copy link
Copy Markdown

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

Project Deployment Actions Updated (UTC)
chuijun-client Ready Ready Preview, Comment Jul 3, 2026 5:09am

@tlrdmsEjrqhRdl
tlrdmsEjrqhRdl marked this pull request as ready for review July 3, 2026 05:09
@tlrdmsEjrqhRdl
tlrdmsEjrqhRdl merged commit 15a136e into develop Jul 3, 2026
6 checks passed
@tlrdmsEjrqhRdl
tlrdmsEjrqhRdl deleted the fix/ui branch July 3, 2026 05:09

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Code Review

This pull request simplifies the filter state management in ProblemBoard and introduces transition-based loading states using isPending to improve user experience. It also refactors the profile image preview logic in ProfileEditDialog from useMemo to useState and useEffect for better cleanup. The review feedback suggests combining isPending with isFetching from useSuspenseQuery to properly capture loading states during debounced search updates, and splitting the preview URL useEffect into two separate hooks to avoid redundant object URL creations.

Important

The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.

function ProblemBoardResults({
keyword,
currentPage,
isPending,

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

high

useDebouncedValue 내부에서 전역 startTransition을 사용하여 디바운스된 검색어를 업데이트하기 때문에, ProblemBoard 컴포넌트의 useTransition에서 반환된 isPending은 검색어 변경으로 인한 재조회(fetching) 상태를 감지하지 못합니다.

이로 인해 사용자가 검색어를 입력하고 결과를 기다리는 동안 화면에 아무런 로딩 표시(불투명도 조절 및 하단 안내 메시지)가 나타나지 않아 UI가 멈춘 것처럼 보일 수 있습니다.

이를 해결하기 위해 useSuspenseQuery가 반환하는 isFetching 상태를 가져와 isPending과 함께 결합한 showPending 변수를 정의하여 사용하는 것을 권장합니다. 이렇게 하면 페이지네이션 전환뿐만 아니라 검색어 입력에 따른 데이터 조회 중에도 로딩 상태가 올바르게 표시됩니다.

추천하는 변경 사항:

  1. useSuspenseQuery에서 isFetching을 구조 분해 할당으로 가져오고, showPending 변수를 정의합니다:
const { data: problemPage, isFetching } = useSuspenseQuery(
  problemKeys.list(currentPage - 1, rowsPerPage, keyword),
);

const showPending = isPending || isFetching;
  1. 아래의 불투명도 조절(line 84) 및 로딩 메시지 표시(line 213) 조건에서 isPending 대신 showPending을 사용하도록 수정합니다.

Comment on lines +83 to +85
className={`border-line bg-surface overflow-hidden rounded-lg border transition-opacity ${
isPending ? "opacity-60" : "opacity-100"
}`}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

medium

검색어 입력 시에도 로딩 상태(불투명도 60%)가 올바르게 적용되도록 isPending 대신 showPending을 사용하도록 수정합니다. (상단 컴포넌트 정의 부분에서 showPending 정의가 필요합니다.)

Suggested change
className={`border-line bg-surface overflow-hidden rounded-lg border transition-opacity ${
isPending ? "opacity-60" : "opacity-100"
}`}
className={`border-line bg-surface overflow-hidden rounded-lg border transition-opacity ${
showPending ? "opacity-60" : "opacity-100"
}`}

Comment on lines +213 to +217
{isPending ? (
<p className="text-muted text-center text-xs" aria-live="polite">
문제 목록을 불러오는 중이에요.
</p>
) : null}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

medium

검색어 입력 시에도 하단의 로딩 안내 메시지가 올바르게 표시되도록 isPending 대신 showPending을 사용하도록 수정합니다. (상단 컴포넌트 정의 부분에서 showPending 정의가 필요합니다.)

Suggested change
{isPending ? (
<p className="text-muted text-center text-xs" aria-live="polite">
문제 목록을 불러오는 중이에요.
</p>
) : null}
{showPending ? (
<p className="text-muted text-center text-xs" aria-live="polite">
문제 목록을 불러오는 중이에요.
</p>
) : null}

Comment on lines 25 to +37
useEffect(() => {
if (!selectedFile) {
setPreviewUrl(profile.profileImageUrl);
return;
}

const objectUrl = URL.createObjectURL(selectedFile);
setPreviewUrl(objectUrl);

return () => {
if (selectedFile && previewUrl.startsWith("blob:")) {
URL.revokeObjectURL(previewUrl);
}
URL.revokeObjectURL(objectUrl);
};
}, [previewUrl, selectedFile]);
}, [profile.profileImageUrl, selectedFile]);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

medium

현재 하나의 useEffect에서 profile.profileImageUrlselectedFile을 모두 감시하고 있어, 파일이 선택된 상태(selectedFile이 존재할 때)에서 profile.profileImageUrl이 변경되면 불필요하게 URL.createObjectURL이 다시 호출되어 새로운 Object URL을 생성하게 됩니다.

역할을 명확히 분리하여, 프로필 이미지 URL 동기화와 선택된 파일의 Object URL 생성/해제 로직을 두 개의 독립된 useEffect로 나누는 것을 권장합니다. 이렇게 하면 불필요한 부수 효과(Side Effect) 발생을 방지하고 코드의 가독성을 높일 수 있습니다.

  useEffect(() => {
    if (!selectedFile) {
      setPreviewUrl(profile.profileImageUrl);
    }
  }, [profile.profileImageUrl, selectedFile]);

  useEffect(() => {
    if (!selectedFile) return;

    const objectUrl = URL.createObjectURL(selectedFile);
    setPreviewUrl(objectUrl);

    return () => {
      URL.revokeObjectURL(objectUrl);
    };
  }, [selectedFile]);

@tlrdmsEjrqhRdl
tlrdmsEjrqhRdl restored the fix/ui branch July 3, 2026 05:20
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant