react drag and drop list - TEAM-ARK/inflearn-clone-front GitHub Wiki
์ง๋๋ฒ ์์ javascript๋ง์ผ๋ก animation์ด ์๋ drag and drop list๋ฅผ ๋ง๋ค๋ ค๋ค๊ฐ ์ ๋์ง ์์๋ค.
javascript๋ก ์ง์ ๊ตฌํํ๋ ค ํ์ผ๋ ์ ๋๋ฉ์ด์ ๋ฐ๋ ๋์ค DOM์ ๋ณ๊ฒฝํ๊ฑฐ๋ (DOM ์์น๊ฐ ๋ฐ๋๋ฉด ์ ๋๋ฉ์ด์ ์ด ๋ฐ๋ ์์น๋ฅผ ๊ธฐ์ค์ผ๋ก ๋์ํ๊ธฐ ๋๋ฌธ์ ๊ณ์ฐ์ด ์ด๋ ต๋ค) ์ ๋๋ฉ์ด์ ์ด ๋๋๊ธฐ ์ ์ ์ ๋๋ฉ์ด์ ์ ๋์ฐฉ์ง์ ์ ๋ณ๊ฒฝํ๋ ๊ฒ์ด ์ด๋ ค์์ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ์ฌ์ฉํ๊ธฐ๋ก ํ๋ค
๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ์ฌ์ฉํ๊ธฐ๋ก ๊ฒฐ์ ํ๊ณ ์ด๋ฒ์ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ์ฌ์ฉํด์ ๊ตฌํํ ๋ด์ฉ์ ์ ๋ฆฌํด๋ณด๋ คํ๋ค.
- sortablejs vs react-sortable-hoc vs react dnd
- Weekly Downloads : ์ฝ 80๋ง
- ์๋ฐ์คํฌ๋ฆฝํธ์์ ์ฌ์ฉํ๊ธฐ ์ํด์ ๋ง๋ค์ด์ง ๋ผ์ด๋ธ๋ฌ๋ฆฌ
- sortablejs ์์
- react-sortablejs๋ฅผ ์ฌ์ฉํ๋ฉด ๋ฆฌ์กํธ์์๋ ํธํ๊ฒ ์ฌ์ฉ๊ฐ๋ฅ
- Weekly Downloads : ์ฝ 8๋ง
- Weekly Downloads : ์ฝ 46๋ง
- ์์ ๊ฐ ์ ๋์ด์๋ค
- react-sortable-hoc ์์
- Weekly Downloads : ์ฝ 81๋ง
- drag and drop react ๋ผ์ด๋ธ๋ฌ๋ฆฌ ์ค ๊ฐ์ฅ ๋ง์ด ์ฌ์ฉ๋๋ค
- inflearn ์ ๋๋ฉ์ด์ ๊ณผ ๊ฐ์ฅ ์ ์ฌํ ๊ฒ
- sortablejs๊ฐ ๊ฑฐ์ ๋๊ฐ๊ณ ๋๋จธ์ง mouseup ๊ณผ mousedown์์ ์ ๋๋ฉ์ด์ ์ด ์ด๋๋๋ ๋ฐฉ์์ด์๋ค(drag api๋ฅผ ์ฌ์ฉํ์ง ์๋ ๊ฒ์ผ๋ก ๋ณด์)
npm install --save react-sortablejs sortablejs
npm install --save-dev @types/sortablejs
-
force flag๋ฅผ ์ฌ์ฉํด์ ์ค์น๋ฅผ ํ๋ค.
// ์ฌ์ฉ ์ - ์ฝ๋ 1
const { createLectureData, lectureData, saveCourseInfoDone } = useSelector((state: RootState) => state.lecture);
const [whatYouCanLearn, setWhatYouCanLearn] = useState<ItemInterface[]>(
lectureData?.courseInfo.whatYouCanLearn.map((item) => ({
id: item.order,
name: item.name,
}))
);
<ReactSortable list={whatYouCanLearn} setList={setWhatYouCanLearn} animation={200} handle=".handle">
{whatYouCanLearn.map((item, index) => (
<TextListBox key={item.id} item={item} list={whatYouCanLearn} setList={setWhatYouCanLearn} index={index} />
))}
</ReactSortable>
// react-sortablejs์์ ๊ถ์ฅํ๋ item type interface - ์ฝ๋ 2
export interface ItemInterface {
/** The unique id associated with your item. It's recommended this is the same as the key prop for your list item. */
id: string | number;
/** When true, the item is selected using MultiDrag */
selected?: boolean;
/** When true, the item is deemed "chosen", which basically just a mousedown event. */
chosen?: boolean;
/** When true, it will not be possible to pick this item up in the list. */
filtered?: boolean;
[property: string]: any;
}
// ๋ด๊ฐ ์ฌ์ฉํ๋ item์ type - ์ฝ๋ 3
export type LectureInfoChild = {
name: string;
order: number | string;
};
// react-sortablejs์ ๋ง๊ฒ ๋ณํ - ์ฝ๋ 4
useEffect(() => {
setWhatYouCanLearn(
lectureData?.courseInfo.whatYouCanLearn.map((item) => ({
id: item.order,
name: item.name,
}))
);
}, [lectureData?.courseInfo]);
- react-sortablejs ๊ณต์ ๋ฌธ์์ key๋ฅผ ๋ฐฐ์ด์ index๋ก ์ฌ์ฉํ์ง ๋ง๋ผ๊ณ ํ๋ค.
DO NOT use the index as a key for your list items. Sorting will not work.
In all the examples above, I used an object with an ID. You should do the same!
I may even enforce this into the design to eliminate errors.
-
ํ์ ์คํฌ๋ฆฝํธ๋ฅผ ์ฌ์ฉํ๋ฉด์ ํ์ ์ด ๋ง์ง ์์ผ๋ฉด ์ผ๋ถ๋ก ํ์ ์ ๋ง์ถ๋ ค๋ ์ฝ๋๋ค์ด ์๋ค.(์ฝ๋ 4๊ฐ์ ๊ฒฝ์ฐ) ํ์ ์ ๋ง์ถ๊ธฐ ์ํ ์ด๋ฐ ๊ฒ์ด ์ ํ๊ณ ์๋ ๊ฒ์ธ์ง ์๋์ง ์ค์ค๋ก ํ๋จํ๊ธฐ ์ด๋ ค์ด ๊ฒ ๊ฐ๋ค.
-
react-sortablejs์์ ๋ฆฌ์คํธ ์์ดํ ์ ์ ์ฒด๊ฐ ์๋ ํน์ ๋ถ๋ถ๋ง ๋๋๊ทธ๋ฅผ ๊ฐ๋ฅํ๊ฒ ๋ง๋ค๊ณ ์ถ์ ๊ฒฝ์ฐ(ํธ๋ค์ ์ฌ์ฉ) ์ฝ๋ 1์์
ReactSortable์ปดํฌ๋ํธ์ handle=".handle" ์์ฑ
์์ ํด๋์ค ์ด๋ฆ์ ์ง์ ํ ์์ดํ ์ปดํฌ๋ํธ์ ํธ๋ค ๋ถ๋ถ์ ํด๋์ค ์ด๋ฆ์ ๋ง์ถฐ์ฃผ๋ฉด ๋๋ค.
<DynamicBox>
<div>{item.name}</div>
<div>
<button onClick={onClickDelete} type="button">
<DeleteIcon />
</button>
<DraggableButton className="handle"> // ํธ๋ค์ ์ํ ํด๋์ค ์ด๋ฆ ์ง์
<DragHandleIcon />
</DraggableButton>
</div>
</DynamicBox>