1. 문제 상황
- React-Sortablejs 사용 시 드래그하는 동안 요소가 반투명해지는 현상 발생
- 기본적으로 HTML5 Drag & Drop API의 기본 동작으로 인해 발생하는 문제
2. 원인 분석
기술적 원인
- HTML5 Drag & Drop API는 드래그 중인 요소에 자동으로 투명도를 적용
- 브라우저의 기본 동작으로, 사용자에게 드래그 상태를 시각적으로 표시하기 위한 것
- React-Sortablejs가 기본적으로 HTML5 Drag & Drop API를 사용하기 때문에 발생
- 때문에 결과적으로 2개의 스타일이 중첩 적용됨
스타일 중첩 문제
// forceFallback이 false일 때 (기본값)
const StyledSortable = styled(ReactSortable)<{ list: Todo[] }>`
display: flex;
flex-direction: column;
gap: 20px;
.sortable-ghost {
opacity: 0.5; // 원래 위치에 남는 고스트 이미지는 완전히 불투명하게
background-color: #f0f0f0; // 고스트 이미지 배경색
border: 2px dashed #ccc; // 고스트 이미지 테두리
}
.sortable-drag {
opacity: 1 !important;
border: 2px dashed blue;
}
`;
- HTML5 기본 투명도 효과와 커스텀 스타일이 동시에 적용됨
- 의도하지 않은 시각적 효과가 발생하는 원인이 됨
3. 해결 방법
<ReactSortable
forceFallback={true}
// 기타 props...
>
{/* 컴포넌트 내용 */}
</ReactSortable>
4. 해결 원리
forceFallback={true}
설정으로 HTML5 Drag & Drop API 대신 Sortable.js의 자체 구현 사용- HTML5 기본 투명도 효과 제거
- 설정한 커스텀 스타일만 깔끔하게 적용됨
5. 스타일 적용 비교
forceFallback={false} (기본값)
- HTML5 기본 투명도 + 커스텀 스타일 중첩 적용
- 의도하지 않은 시각적 효과 발생
forceFallback={true}
- HTML5 기본 효과 제거
- 커스텀 스타일만 적용
- 의도한 대로 깔끔한 드래그 효과 구현
6. 장점
- 구현 용이성
- 단일 prop 설정으로 문제 해결
- 추가적인 CSS나 JavaScript 코드 불필요
- 일관성
- 브라우저 간 동일한 동작 보장
- 커스터마이징이 용이
7. 참고사항
- 필요한 경우 추가적인 스타일링을 통해 드래그 상태를 시각적으로 표현 가능
ghostClass
,dragClass
등의 props를 활용하여 드래그 중인 요소의 스타일 커스터마이징 가능
※ 만약에 데이터를 동적으로 추가할 경우엔 이 방법을 사용하면 안됩니다. 새로 추가한 배열이 있다면 드래그가 막히기 때문에 직접 드래그를 구현하거나 다른 솔트 방법을 사용해야합니다.
8. 관련 코드 예시
<StyledSortable
list={todos}
setList={handleSetList}
animation={150}
ghostClass="sortable-ghost"
dragClass="sortable-drag"
handle=".drag-handle"
forceFallback={true}
>
const StyledSortable = styled(ReactSortable)<{ list: Todo[] }>`
display: flex;
flex-direction: column;
gap: 20px;
.sortable-ghost {
opacity: 0.5; // 원래 위치에 남는 고스트 이미지는 완전히 불투명하게
background-color: #f0f0f0; // 고스트 이미지 배경색
border: 2px dashed #ccc; // 고스트 이미지 테두리
}
.sortable-drag {
opacity: 1 !important;
border: 2px dashed blue;
}
`;