react-useful-dnd

0.1.0 โ€ข Public โ€ข Published

React Useful DnD ๐ŸŽ‡ โ†’ ๐ŸŒ

react์—์„œ drag & drop ๊ธฐ๋Šฅ์„ ํŽธํ•˜๊ฒŒ ์‚ฌ์šฉํ•˜๊ธฐ ์œ„ํ•ด ๊ตฌํ˜„ํ•œ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ์ž…๋‹ˆ๋‹ค.

custom hooks๋กœ ๊ตฌํ˜„ํ•˜์˜€์œผ๋ฉฐ drag & drop์„ ์ ์šฉํ•˜๊ณ  ์‹ถ์€ component์—์„œ ํ•ด๋‹น ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ํ˜ธ์ถœํ•˜์—ฌ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.


๐Ÿ’ป install

yarn add react-useful-dnd

npm install react-useful-dnd

โœ๏ธ usage

component๋ฅผ dragํ•  ์ˆ˜ ์žˆ๋„๋ก ํ•˜๊ธฐ ์œ„ํ•ด์„œ๋Š” useDraggable ์„ ์‚ฌ์šฉํ•˜๊ณ , drag์š”์†Œ๋ฅผ dropํ•˜๊ธฐ ์œ„ํ•ด์„œ๋Š” useDroppable ์„ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.

drag์š”์†Œ๊ฐ„์˜ state๊ด€๋ฆฌ๋ฅผ ์œ„ํ•ด useDnDContext๋ฅผ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.


๐Ÿ•‹ useDnDContext

useDnDContext hooks๋Š” drag ๊ฐ€๋Šฅํ•œ ์š”์†Œ๋“ค์˜ ์ƒํƒœ๊ด€๋ฆฌ๋ฅผ ์ œ์–ดํ•˜๊ธฐ ์œ„ํ•ด ์กด์žฌํ•˜๋Š” ์š”์†Œ์ž…๋‹ˆ๋‹ค. ์ดˆ๊ธฐ ์ƒํƒœ๊ฐ’์„ ์ธ์ž๋กœ ๋ฐ›์Šต๋‹ˆ๋‹ค.

์ดˆ๊ธฐ ์ƒํƒœ๊ฐ’์€ ๋‹ค์Œ๊ณผ ๊ฐ™์€ ํ˜•์‹์„ ๊ฐ–๋Š” data์ด์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

const initialState = {
	first: { data: [...] },
	second: { data: [...] }
};

๊ฐ์ฒด์ด๋ฉฐ key๊ฐ’์€ ํ•ด๋‹น droppable์˜ id๊ฐ€ ๋  ๊ฐ’, value๊ฐ’์€ ์ƒํƒœ๊ด€๋ฆฌ๊ฐ€ ์ด๋ฃจ์–ด์งˆ ๊ฐ’์ด ๋˜๋Š” ๊ฐ’์ž…๋‹ˆ๋‹ค.

useDnDContext๋ฅผ ํ˜ธ์ถœํ•˜๋ฉด DnDStore, DnDContext, droppableIds๋ฅผ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค. ๊ฐ๊ฐ, Store jsx, context, droppable์„ ๋Œ€ํ‘œํ•˜๋Š” id ๋ฐฐ์—ด์„ ์˜๋ฏธํ•ฉ๋‹ˆ๋‹ค.

๋‹ค์Œ๊ณผ ๊ฐ™์€ ํ˜•์‹์œผ๋กœ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

import React from "react";
import DropZone from "DropZone";
import { useDnDContext } from "react-useful-dnd";

const firstItem = [1, 2, 3, 4, 5];
const secondItem = [6, 7, 8, 9, 10];

const initialState = {
	first: { data: firstItem },
	second: { data: secondItem }
};

function App() {
	const [DnDStore, DnDContext, droppableIds] = useDnDContext(initialState);

	return (
		<DnDStore>
			{droppableIds.map(id => (
				<DropZone key={id} id={id} context={DnDContext} />
			))}
		</DnDStore>
	);
}

export default App;

DnDStore ๋‚ด๋ถ€์—์„œ ์‚ฌ์šฉ๋˜๋Š” Droppableํ•œ ์š”์†Œ๋Š” id์™€ contexts๋ฅผ props๋กœ ๋„˜๊ฒจ์ฃผ์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

๐ŸŽ‡ useDraggable

useDraggable hooks๋Š” ๋ฐฐ์—ด ํ˜•ํƒœ์˜ ๊ฐ’์„ ๋ฐ˜ํ™˜ํ•˜๋ฉฐ, option ๊ฐ์ฒด๋ฅผ ์ธ์ž๋กœ ๋„˜๊ฒจ์ฃผ์–ด์—ฌ ํ•ฉ๋‹ˆ๋‹ค.

option ๊ฐ์ฒด๋Š” droppableId, groupId๋ฅผ ํ”„๋กœํผํ‹ฐ๋กœ ๊ฐ€์ง€๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. droppableId๋Š” ํ•ด๋‹น dropzone์˜ id๊ฐ€ ๋  ๊ฐ’์ด๋ฉฐ ๋„˜๊ฒจ์ฃผ์ง€ ์•Š์œผ๋ฉด ์ž๋™์œผ๋กœ ์ƒ์„ฑ๋ฉ๋‹ˆ๋‹ค. groupId๋Š” ํ•ด๋‹น draggable ์š”์†Œ๊ฐ€ ์†ํ•œ context์˜ id์ž…๋‹ˆ๋‹ค.

๋ฐฐ์—ด์˜ ์ฒซ๋ฒˆ์งธ ์š”์†Œ๋Š” ํ•ด๋‹น component๋ฅผ ๊ฐ€๋ฆฌํ‚ค๊ฒŒ ๋  ref์ด๋ฉฐ, ๋‘๋ฒˆ์งธ ์š”์†Œ๋Š” ํ•ด๋‹น component์˜ id ์ž…๋‹ˆ๋‹ค.

ํ•ด๋‹น component์˜ ์ƒ์œ„ ํƒœ๊ทธ์— ref์™€ id props๋ฅผ ๋ถ€์—ฌํ•ด์คŒ์œผ๋กœ์จ ์‚ฌ์šฉ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค.

import React from "react";
import { useDraggable } from "react-useful-dnd";

function Draggable({ data, groupId, droppableId }) {
	const [draggableRef, id] = useDraggable({ droppableId, groupId });

	return (
		<div ref={draggableRef} id={id}>
			<h3>Draggable #{data}</h3>
		</div>
	);
}

export default Draggable;

๐ŸŒ useDroppable

useDroppable hooks ๋˜ํ•œ ๋ฐฐ์—ด ํ˜•ํƒœ์˜ ๊ฐ’์„ ๋ฐ˜ํ™˜ํ•˜๋ฉฐ option ๊ฐ์ฒด๋ฅผ ์ธ์ž๋กœ ๋„˜๊ฒจ์ฃผ์–ด์—ฌ ํ•ฉ๋‹ˆ๋‹ค.

option ๊ฐ์ฒด๋Š” id, context๋ฅผ ํ”„๋กœํผํ‹ฐ๋กœ ๊ฐ€์ง€๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. id๋Š” ํ•ด๋‹น dropzone์˜ id๊ฐ€ ๋  ๊ฐ’์ด๋ฉฐ ๋„˜๊ฒจ์ฃผ์ง€ ์•Š์œผ๋ฉด ์ž๋™์œผ๋กœ ์ƒ์„ฑ๋ฉ๋‹ˆ๋‹ค. context๋Š” ํ•ด๋‹น droppable ์š”์†Œ๊ฐ€ ์†ํ•œ store์˜ context์ž…๋‹ˆ๋‹ค.

useDroppable hooks๋ฅผ ํ˜ธ์ถœํ•˜์—ฌ ๋ฐ˜ํ™˜๋˜๋Š” ๋ฐฐ์—ด์˜ ์ฒซ๋ฒˆ์งธ ์š”์†Œ๋Š” ํ•ด๋‹น component๋ฅผ ๊ฐ€๋ฆฌํ‚ค๊ฒŒ ๋  ref์ด๋ฉฐ, ๋‘๋ฒˆ์งธ ์š”์†Œ๋Š” ํ•ด๋‹น component์˜ id ์ž…๋‹ˆ๋‹ค.

์„ธ๋ฒˆ์งธ ์š”์†Œ์ธ datas๋Š” ํ•ด๋‹น droppable ์š”์†Œ์˜ state์ด๋ฉฐ drag & drop ์ด๋ฒคํŠธ์˜ ๊ฒฐ๊ณผ์— ๋”ฐ๋ผ ๋ณ€๊ฒฝ๋ฉ๋‹ˆ๋‹ค. ๋„ค๋ฒˆ์งธ ์š”์†Œ์ธ groupId๋Š” ํ•ด๋‹น droppable ์š”์†Œ๊ฐ€ ์†ํ•œ context์˜ id์ž…๋‹ˆ๋‹ค.

ํ•ด๋‹น component์˜ ์ƒ์œ„ ํƒœ๊ทธ์— ref์™€ id props๋ฅผ ๋ถ€์—ฌํ•ด์คŒ์œผ๋กœ์จ ์‚ฌ์šฉ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค. draggable ์š”์†Œ์— groupId์™€ droppableId๋ฅผ props๋กœ ๋„˜๊ฒจ์ฃผ์–ด draggable ์š”์†Œ์—์„œ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋„๋ก ํ•ด์ฃผ์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.


import React from "react";
import { useDraggable } from "react-useful-dnd";
import Draggable from "Draggable";

function DropZone({ id, context }) {
	const [droppableRef, droppableId, datas, groupId] = useDroppable({
		id,
		context
	});

	return (
		<div id={droppableId} ref={droppableRef}>
			{datas.map(item => (
				<Draggable
					key={groupId + "-" + droppableId + "-" + item}
					data={item}
					groupId={groupId}
					droppableId={droppableId}
				/>
			))}
		</div>
	);
}

export default DropZone;

Package Sidebar

Install

npm i react-useful-dnd

Weekly Downloads

3

Version

0.1.0

License

none

Unpacked Size

29.8 kB

Total Files

10

Last publish

Collaborators

  • wltn3231