728x90
🧨 문제 상황 및 원인 분석
파일 리스트에서 드래그 기능을 구현하던 중, 선택된 항목을 기반으로 데이터를 설정하려 했지만 selectedItems가 undefined로 나와 드래그 대상 판단이 되지 않았음.
🧪 시행착오 및 중간 시도들
- useCallback 의존성에 selectedItems 포함 → 여전히 drag 이벤트 시점에서는 반영되지 않음
- useEffect에서 selectedItems 확인 시 정상 → 렌더 타이밍과 이벤트 타이밍 불일치
- 최종적으로 클로저 문제로 판단
🧾 개선 코드 (배열만 처리)
const selectedItemsRef = useRef<string[]>([]);
useEffect(() => {
selectedItemsRef.current = selectedItems;
}, [selectedItems]);
const handleDrag = useCallback((event, rowId) => {
if (!event) return;
const currentSelection = selectedItemsRef.current;
const isSelected = currentSelection.includes(rowId);
const dragData = isSelected
? dataList.filter(item => currentSelection.includes(item.id))
: [rowId];
event.dataTransfer?.setData('application/json', JSON.stringify(dragData));
}, [dataList]);
🧠 정리 및 교훈
- useCallback 내부에서는 상태가 클로저에 의해 과거 값으로 고정될 수 있음
- 특히 drag, scroll, resize 같은 브라우저 이벤트에서는 이 문제로 인해 로직이 오작동할 수 있음
- 최신 상태값을 안정적으로 유지하려면 useRef를 사용하여 외부 상태를 동기화해야 함
- selection이 항상 배열일 경우, 조건을 단순화해 코드 가독성과 안정성을 확보할 수 있음
728x90
'버그 케이스별 대응 기록 & 컴포넌트별 동작 구조 도식화' 카테고리의 다른 글
MUI DataGridPro에서 "Rendered fewer hooks than expected" 오류 해결기 – renderCell 내 Hook 분리로 해결 (0) | 2025.06.10 |
---|---|
Material UI Popper 컴포넌트 버그 케이스 대응 기록 및 동작 구조 (0) | 2025.04.22 |
댓글