라이브러리는 react-beautiful-dnd npm 사이트에서 가져와서 사용했다.
npm i react-beautiful-dnd
첫 번째 시도
프로젝트 진행 중에 멀티 이미지를 업로드하고 드래그 앤 드롭으로 이미지 순서를 변경할 수 있는 기능을 만들게 되어 찾아보던 중 위 블로그를 보게 되었고 적용했을 때 아래 사진과 같이 console에 오류가 발생하여 적용하지 못했다.
두 번째 시도
해결책을 찾지 못해 이번에는 키워드를 Next.js 이미지 순서 변경이라고 검색해서 아래 블로그를 발견했다.
이 블로그에서는 처음에 봤던 블로그와 달리 DragLand라는 컴포넌트에서 useEffect를 사용하여 컴포넌트가 생성된 후 Drag 컴포넌트를 호출하는 방법을 사용하셨다. 결과는 성공적이었다.
문제 해결
그때 문득 의문이 생겼다.
첫 번째 블로그와 두 번째 블로그를 비교해 봤을 때 크게 다른 부분은 useEffect의 사용 유무였다.
첫 번째 블로그 예제에 DragLand 코드를 적용해 보니 문제점이 해결되었다.
결국 컴포넌트가 생성되기 전에 라이브러리가 호출되어서 발생한 문제였던 것 같다.
두 개의 코드를 적절히 섞어 보았다.
// React 관련 요소
import { useEffect, useState } from "react";
// 드래그 요소
import { DragDropContext, Draggable, Droppable } from "react-beautiful-dnd";
// 스타일 정의
import styled from "styled-components";
const DragContent = styled.div`
border: 1px solid lightgrey;
`;
const DragLand = () => {
// window가 로드 된 시점에서 렌더링
const [winReady, setwinReady] = useState(false);
useEffect(() => {
setwinReady(true);
}, []);
return (
<>
{/* 윈도우, DOM 로드 시점에서 드래그 생성 */}
{winReady ? <Drag /> : null}
</>
);
};
// 드래그 요소 생성
export const Drag = () => {
const [todos, setTodos] = useState([
{ id: "1", title: "공부" },
{ id: "2", title: "헬스" },
{ id: "3", title: "독서" },
{ id: "4", title: "산책" },
{ id: "5", title: "요리" },
]);
const handleChange = (result) => {
if (!result.destination) return;
console.log(result);
const items = [...todos];
const [reorderedItem] = items.splice(result.source.index, 1);
items.splice(result.destination.index, 0, reorderedItem);
setTodos(items);
};
return (
<>
{/* 드래그 영역 */}
<DragDropContext onDragEnd={handleChange}>
{/* 드래그 놓을 수 있는 영역 */}
<Droppable droppableId="DropLand">
{/* 드래그 Div 생성 */}
{(provided, snapshot) => (
// CCS가 적용된 Div
<DragContent {...provided.droppableProps} ref={provided.innerRef}>
{todos.map((data, index) => (
<Draggable key={data.id} draggableId={data.id} index={index}>
{(provided, snapshot) => (
<Content
ref={provided.innerRef}
{...provided.draggableProps}
{...provided.dragHandleProps}
>
{data.title}
</Content>
)}
</Draggable>
))}
{provided.placeholder}
</DragContent>
)}
</Droppable>
</DragDropContext>
</>
);
};
const Content = styled.div`
margin: 8px;
padding: 10px;
border: 1px solid lightgrey;
background: aliceblue;
border-radius: 2px;
`;
export default DragLand;
+ 2023.02.07 - 특정 부분만 드래그 가능하도록 하는 방법
위에서 구현했던 기능에서는 박스 전체에서 드래그로 순서 변경이 가능했기 때문에
추가로 특정 부분을 드래그했을 때만 박스 순서를 변경할 수 있는 기능을 구현하고 싶었다.
많은 시행착오가 있었지만... 마음을 다잡고 천천히 해보니 쉽게 해결 가능한 부분이었다.
위에서 구현했던 코드를 살펴보면
Draggable이 드래그할 박스들의 영역이고, children에 div 태그에는 ref와 draggableProps, dragHandleProps가 있어서 이 부분을 중점적으로 보았을 때 dragHandlerProps는 드래그 기능을 담당하는 부분인 것 같고 draggableProps는 드래그로 순서 이동 했을 때 해당 값들을 담고 있지 않을까.. 생각이 들어서
아래처럼 {.. provided.dragHandleProps}를 div 태그에서 p 태그로 옮겨주었다. ☺️👍
'더 알아보기 > 기능' 카테고리의 다른 글
[React] 마우스로 드래그 스크롤 구현하기 - 라이브러리 O (0) | 2022.07.04 |
---|---|
[Next.js] 다중 이미지 업로드 및 미리보기 + 드래그로 순서 변경 (0) | 2022.06.28 |
[JS] 객체 👉 배열 / 배열 👉 객체 (0) | 2022.05.27 |
[React] 방 추가, 삭제 기능 만들기(객체 삽입, 삭제, 수정) (0) | 2022.05.24 |
[CSS] animation, @keyframes를 사용한 화면 전화 CSS (0) | 2022.05.13 |
댓글