일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | ||||
4 | 5 | 6 | 7 | 8 | 9 | 10 |
11 | 12 | 13 | 14 | 15 | 16 | 17 |
18 | 19 | 20 | 21 | 22 | 23 | 24 |
25 | 26 | 27 | 28 | 29 | 30 | 31 |
- iframe
- RGBA
- not 의사클래스
- 인접 형제 결합자
- background-color 속성
- height속성
- sub태그
- 아두이노
- i 태그
- sup태그
- br 태그
- Live Server
- 임베디드
- focus 의사클래스
- html tag i
- html 태그
- width속성
- iframe 태그
- id 선택자
- Checked 의사 클래스
- 자식결합자
- css
- go live
- tag html
- html
- padding 속성
- 일반 형제 결합자
- reveal in file explorer
- 전체 선택자
- RGB
- Today
- Total
so woon!
[REACT] Drag and Drop - 같은 보드 내에서 재정렬 본문
학습일 : 2023. 04. 30
보드를 3개로 늘리면서
보드내에서 재정렬 하던 부분을 주석처리 해놓았었는데
다시 한번 구현해보고자 한다.
한개의 보드 내에서 드로그 앤 드롭 다시 구현하기
드롭할 때마다 onDragEnd 함수가 실행된다.
먼저, source의 droppableId가 destination의 droppableId와 같은지 체크해야 한다.
왜냐하면 아직 보드를 넘어다니지는 않고 한 보드 안에서 움직일 것이기 때문이다.
<App.tsx>
const onDragEnd = (info: DropResult) => {
console.log(info);
const {destination, draggableId, source} = info;
if(destination?.droppableId === source.droppableId) {
// 같은 보드에서의 움직임
}
지금부터 할 것은 전에 했던 거랑 비슷한데
전에 array를 복사해서
그 array를 변형시킨(mutate) 다음 그걸 다시 새로운 array로 저장했다.
이제는 복사할 array가 없는 대신
atom.tsx에 여러 array가 들어있는(미리 작성해둔) object가 있다.
default에 작성해줬던 것이고,
Property들을 가진 object이며 각 property들이 array이다.
-로직-
만약 하나의 보드 내에서 그래그 앤 드롭을 다시 구현하고자 한다면
1. 수정이 일어난 보드만 복사한다.
2. 그리고 그 복사본을 기존 친구들 옆에 붙여준다.
복붙 전
<App.tsx>
const onDragEnd = (info: DropResult) => {
console.log(info);
const {destination, draggableId, source} = info;
if(destination?.droppableId === source.droppableId) {
// 전에 적어줬던 로직을 다시 붙여넣기 해줌
}
복붙 후
function App() {
const [toDos, setToDos] = useRecoilState(toDoState);
const onDragEnd = (info: DropResult) => {
console.log(info);
const { destination, draggableId, source } = info;
if (destination?.droppableId === source.droppableId) {
setToDos((oldToDos) => {
const toDosCopy = [...oldToDos];
toDosCopy.splice(source.index, 1);
toDosCopy.splice(destination?.index, 0, draggableId);
return toDosCopy;
});
}
};
그런데 oldToDos는 더이상 array가 아니라서
...oldToDos 이렇게 쓸 수는 없으니 지워주고
이제 변화가 일어난 board만 복사해줄 것이다.
destination?.droppableId === source.droppableId 서로 같다는 전제 하라서
둘 중 아무거나 써줘도 상관 없음.
boardCopy를 만들어준다.
oldToDos로 들어가서 source.droppableId를 가져온다.
<App.tsx>
관련 로직은 주석으로 적었음.
function App() {
const [toDos, setToDos] = useRecoilState(toDoState);
// onDragEnd : 드래그가 끝났을 때 실행되는 함수
// destination : 드래그 끝나는 시점의 도착지 정보
// source : 드래그 시작 정보 - 움직임을 시작한 아이템의 index, droppableId를 알려줌
const onDragEnd = (info: DropResult) => {
console.log(info);
const { destination, draggableId, source } = info;
// destination이 정의되지 않았을 경우 그대로 리턴
if(!destination) return;
if (destination?.droppableId === source.droppableId) {
setToDos((allBoards) => {
// source의 droppableId로부터 array를 복사하는 과정
const boardCopy = [...allBoards[source.droppableId]]; // toDo or Doing or Done의 array를 복사한다.
// 1. source.index에서 아이템을 삭제한다.
boardCopy.splice(source.index, 1); // source.index 즉 시작시점부터 1개만 지움
// 2. item을 다시 destination.index에 넣고, 아무것도 추가하지 않고 item을 넣는다.
// (item은 draggabledId 이다.)
// (때때로 destination이 없을 수도 있다. 유저가 그자리에 그대로 둘 경우엔)
boardCopy.splice(destination?.index, 0, draggableId);
// boardCopy와, 이전의 State와, 다른 Boards를 모두 리턴해주어야 함
// oldToDos는 object 였다.
// oldToDos에서 모든걸 리턴할건데, 보드 딱 하나만 다른걸로 대체
return {
...allBoards, // 다른 모든 board들을 가져오고
[source.droppableId]: boardCopy, // 새로운 변형된 board. (복사본임)
};
});
}
};
return (
<DragDropContext onDragEnd={onDragEnd}>
<Wrapper>
{/* Object.keys(toDos) 까지 하면 board의 모든 Id를 받아왔음. */}
{/* 그럼 그 boardId로 map을 이용해 새로운 board들을 만들어준다. */}
<Boards>
{Object.keys(toDos).map((boardId) => (
<Board key={boardId} toDos={toDos[boardId]} boardId={boardId} />
))}
</Boards>
</Wrapper>
</DragDropContext>
);
}
export default App;
실행결과
하나의 보드 내에서만 드로그 앤 드롭이 가능함을 볼 수 있음.
'ReactJS > 개념정리' 카테고리의 다른 글
[REACT] Drag and Drop - snapshot의 draggingFromThis (0) | 2023.05.01 |
---|---|
[REACT] Drag and Drop - 여러개의 보드에서의 재정렬 + snapshot의 isDraggingOver (0) | 2023.05.01 |
[React] Drag and Drop - multi board 만들기 (0) | 2023.04.29 |
[REACT] Drag and Drop - onDragEnd, 재정렬 + React.memo() (0) | 2023.04.28 |
[REACT] Drag and Drop - placeholder (0) | 2023.04.26 |