관련 글 목차
1️⃣ react-beautiful-dnd를 사용하여 드래그로 순서 변경하기
2️⃣ 다중 이미지 업로드 및 미리 보기 + 드래그로 순서 변경
3️⃣ 수평 dnd 만들기
들어가며
이번 글은 제목처럼 "드래그 상태에서 css 조작하기"에 관한 글입니다.
⏳ 적용 전
🚀 적용 후
위 예시는 테스트용으로 작성한 코드 실행 화면입니다. (참고용)
table 태그를 사용하여 구현하였더니 tr에 너비가 동일하지 않아서 그 부분은 감안하고 참고해주세요.
적용 코드
1탄에서 사용했던 코드에서 빨간색 선으로 표시한 부분이 추가되었고,
여기서 주의해야 할 부분은 ⭐ style 속성에... provided.draggableProps.style이 드래그 중에 변경되는 스타일을 관리하고, 드래그가 끝났을 때 해당 스타일을 초기화하는 역할을 하기 때문에 해당 코드 아래에 드래그 중에 적용하고 싶은 코드를 작성해야 한다.
더보기
// React 관련 요소
import { useEffect, useRef, 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 tbodyRef = useRef(null)
const [tbodyWidth, setTbodyWidth] = useState("100%")
useEffect(() => {
if (tbodyRef.current) {
const width = tbodyRef.current.offsetWidth
setTbodyWidth(`${width}px`)
}
}, [todos])
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={(el) => {
provided.innerRef(el)
tbodyRef.current = el
}}
>
{todos.map((data, index) => (
<Draggable key={data.id} draggableId={data.id} index={index}>
{(provided, snapshot) => (
<Content
ref={provided.innerRef}
{...provided.draggableProps}
{...provided.dragHandleProps}
style={{
...provided.draggableProps.style, // 드래그 중에 변경되는 스타일을 관리하고, 드래그가 끝났을 때 해당 스타일을 초기화 해준다.
width: tbodyWidth,
justifyContent: "space-around",
}}
>
{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
'더 알아보기 > 기능' 카테고리의 다른 글
[Next.js] Grouping Pagination 만들기 (라이브러리 X) (0) | 2023.12.11 |
---|---|
[Next.js] 드롭다운 영역 외 클릭 시 메뉴 닫기 (2) | 2023.11.27 |
[React + Typescript] Canvas 태그와 useRef를 사용하여 그림판 만들기 (0) | 2023.10.20 |
[React + Typescript] 부모 자식 간에 useRef 사용하는 방법 (0) | 2023.10.19 |
[React-Toastify] 토스트 기능 구현해보기 (0) | 2023.09.26 |
댓글