Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 17 additions & 2 deletions src/feature/album/detail/components/PhotoList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -170,6 +170,7 @@ export default function PhotoList({
const isAllSelected =
selectablePhotos.length > 0 &&
selectablePhotos.every(({ photoId }) => selectedPhotoIds.has(photoId));
const hasAnySelected = selectedPhotos.length > 0;

const selectableStorePhotos = useMemo(
() =>
Expand All @@ -181,7 +182,7 @@ export default function PhotoList({
);

const handleToggleSelectAll = () => {
if (isAllSelected) {
if (hasAnySelected) {
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

isAllSelected에서 hasAnySelected로 조건을 변경하면서, 일부 사진만 선택된 상태에서 전체를 선택하는 기능이 사라졌습니다. 현재 로직에서는 일부라도 선택되어 있으면 "전체 선택 취소"만 가능하여, 사용자가 전체 선택을 하려면 먼저 모든 선택을 해제해야 합니다. 이는 사용자 경험을 저해할 수 있습니다.

예를 들어, 100장 중 99장을 선택한 사용자가 나머지 한 장을 선택하기 위해 "전체 선택"을 누르고 싶을 수 있지만, 현재는 불가능합니다.

세 가지 상태(선택 없음, 일부 선택, 전체 선택)를 구분하여 처리하는 것을 고려해보세요. 예를 들어, 일부만 선택된 상태에서는 여전히 "전체 선택" 버튼을 표시하여 사용자가 나머지 항목을 쉽게 선택할 수 있도록 할 수 있습니다.

setIsSelectAllMode(false);
clearSelectedPhotos();
return;
Expand All @@ -206,6 +207,20 @@ export default function PhotoList({
}
}, [isSelectAllMode, mode, selectableStorePhotos, setSelectedPhotos]);

// includeMyPhotos 토글 변경 시, 필터에서 사라진 사진을 selectedPhotos에서 제거
useEffect(() => {
if (mode !== 'select') return;

const selectableIds = new Set(selectablePhotos.map((p) => p.photoId));
const currentSelected = useSelectedPhotosStore.getState().selectedPhotos;
const filtered = currentSelected.filter((p) => selectableIds.has(p.id));

if (filtered.length !== currentSelected.length) {
setSelectedPhotos(filtered);
setIsSelectAllMode(false);
}
}, [mode, selectablePhotos, setSelectedPhotos]);
Comment on lines +211 to +222
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 내에서 selectablePhotos가 변경될 때마다 new Set(selectablePhotos.map(...))을 통해 selectableIds를 생성하고 있습니다. selectablePhotos가 큰 배열일 경우 성능에 미미한 영향을 줄 수 있습니다.

이 계산은 useMemo를 사용하여 컴포넌트의 최상위 레벨에서 memoization하는 것을 고려해볼 수 있습니다. 이렇게 하면 계산 로직과 부수 효과(side effect) 로직이 분리되어 코드 가독성이 향상되고, 불필요한 재계산을 방지할 수 있습니다.

const selectableIds = useMemo(
  () => new Set(selectablePhotos.map((p) => p.photoId)),
  [selectablePhotos],
);

useEffect(() => {
  if (mode !== 'select') return;

  const currentSelected = useSelectedPhotosStore.getState().selectedPhotos;
  const filtered = currentSelected.filter((p) => selectableIds.has(p.id));

  if (filtered.length !== currentSelected.length) {
    setSelectedPhotos(filtered);
    setIsSelectAllMode(false);
  }
}, [mode, selectableIds, setSelectedPhotos]);

위와 같이 수정하면 useEffect의 의존성이 더 명확해지고 코드가 더 효율적으로 됩니다.


return (
<section ref={photoListRef} className='relative p-4'>
<div ref={anchorRef} className='invisible absolute top-[-72px] left-0' />
Expand Down Expand Up @@ -241,7 +256,7 @@ export default function PhotoList({
}}
onClick={handleToggleSelectAll}
>
{isAllSelected ? '전체 선택 취소' : '전체 선택'}
{hasAnySelected ? '전체 선택 취소' : '전체 선택'}
</button>
<button
type='button'
Expand Down
Loading