TRELLO Clone #3 React-beautiful-dnd(3)

Leesu·2022년 12월 6일
0
  • 이제 하나의 보드가 아닌 여러개의 보드를 만들어보고, 보드와 보드 사이에 카드들이 드래그 앤 드롭될 수 있도록 만들기.
  • 그러기 위해 state 를 object로 만들어준 다음, a,b,c.. 값들을
    to_do, doing, done 3개로 쪼개주었다.
-- atoms.tsx

interface IToDoState {
  [key: string]: string[];
}

export const toDoState = atom<IToDoState>({
  key: "toDo",
  default: {
    "To Do": ["a", "b"],
    Doing: ["c", "d", "e"],
    Done: ["f"],
  },
});
  • 총 3개의 보드를 만들었다. 물론 스타일도 손봐줬다.
  • 이렇게 되면, 문제가 생기는데.
-- App.tsx
		<Boards>
          <Droppable droppableId="one">
            {(magic) => (
              <Board ref={magic.innerRef} {...magic.droppableProps}>
                {toDos.map((toDo, index) => (
                  <DragabbleCard key={toDo} index={index} toDo={toDo} />
                ))}
                {magic.placeholder}
              </Board>
            )}
          </Droppable>
        </Boards>
  • 이 부분에서 생긴다.
  • map 은 object 가 아닌 array 에서만 가능하므로 오류가 나는 것
  • state 에서 오는 3개의 다른 보드를 렌더하기 위해 Board 컴포넌트를 따로 제작,
    그래야 map() 을 써서 board 들이 렌더되게 할 수 있기 때문에.
-- Board.tsx

import { Droppable } from "react-beautiful-dnd";
import styled from "styled-components";
import DragabbleCard from "./DragabbleCard";

const Wrapper = styled.div`
  padding: 20px 10px;
  background-color: ${(props) => props.theme.boardColor};
  border-radius: 5px;
  min-height: 200px;
`;

interface IBoardProps {
  toDos: string[];
  boardId: string;
}

function Board({ toDos, boardId }: IBoardProps) {
  return (
    <Title>{boardId}</Title>
    <Droppable droppableId={boardId}>
      {(magic) => (
        <Wrapper ref={magic.innerRef} {...magic.droppableProps}>
          {toDos.map((toDo, index) => (
            <DragabbleCard key={toDo} index={index} toDo={toDo} />
          ))}
          {magic.placeholder}
        </Wrapper>
      )}
    </Droppable>
  );
}
export default Board;
  • 그리고 아까 오류가 났던 app 컴포넌트 안에 추가.
  • 하기 위해~~

Object.keys(obj)

Object.keys() 메소드는 주어진 객체의 속성 이름들을 일반적인 반복문과 동일한 순서로 순회되는 열거할 수 있는 배열로 반환합니다.
(즉, object 가 가진 key 만 array 로 뽑아내준다!)

  • ex) Object.keys(obj).map((item)=>obj[item])
- 예시 1)

const object1 = {
  a: 'somestring',
  b: 42,
  c: false
};
console.log(Object.keys(object1)); 

// 결과값 ->  Array ["a", "b", "c"]
  • 위의 예시에서 덧붙이자면,
object1['a'] 

// 결과값 -> :"somestring"
  • 이렇게 a 의 자식들을 확인할 수 있다.
  • 이제, borardId 가 있으니, boardId 가 각각 가지는 자식들을 확인할 수 있다.
-- App.tsx
		<Boards>
          {Object.keys(toDos).map((boardId) => (
            <Board boardId={boardId} key={boardId} toDos={toDos[boardId]} />
          ))}
        </Boards>
  • 그럼 아래와 같이, 완성!

Same Board Movement

  • 우선, 같은 보드 내에서 드래그 앤 드롭되도록 만들 것이다.
  • 여기서 잊지 말아야할 것 !!
    • DropResult
      • draggableId: 드래그 되었던 Draggable의 id
      • source: Draggable이 시작된 위치
      • destination: Draggable이 끝난 위치
  • 이전과 같으면서도 다른 방법으로 index 를 움직여줘야한다.
      1. 같은 보드 내에서 움직여야 하므로, source board 가 destination board 와 같은지 체크해준다.
      1. 수정이 일어난 보드만 복사해준다.
      1. 복사된 복사본을 기존 친구들 옆에 붙여준다.
      1. state return 시 boardCopy, State, 다른 Boards 를 모두 return 해준다.
-- App.tsx 

const onDragEnd = (info: DropResult) => {
    console.log(info);
    const { destination, draggableId, source } = info;
    if(!destination) return;
    if (destination?.droppableId === source.droppableId) {
      // same board movement.
      setToDos((allBoards) => {
        const boardCopy = [...allBoards[source.droppableId]];
        boardCopy.splice(source.index, 1);
        boardCopy.splice(destination?.index, 0, draggableId);
        return {
          ...allBoards,
          [source.droppableId]: boardCopy,
            // "Doing" : boardCopy,
            // 히히 이제 doing 은 board 의 복사본이다.
        };
      });
    }

Cross Board Movement

  • 이제, 같은 보드 내에서 움직이는 것이 아닌, 다른 보드와 보드에서 카드들이 드래그 앤 드롭될 수 있도록 하자!
    1. 같은 보드 내에서 움직이는 것이 아니므로, sourcedestination 각각 복사해주어야한다!
    1. 여기서부터는 이전과 같은 방법으로 ~
-- App.tsx

if (destination.droppableId !== source.droppableId) {
      // cross board movement
      setToDos((allBoards) => {
        const sourceBoard = [...allBoards[source.droppableId]];
        const destinationBoard = [...allBoards[destination.droppableId]];
        sourceBoard.splice(source.index, 1);
        destinationBoard.splice(destination?.index, 0, draggableId);
        return {
          ...allBoards,
          [source.droppableId]: sourceBoard,
          [destination.droppableId]: destinationBoard,
        };
      });
    }
  • 완성!

  • DOING 에 있던 'D' 를 TO_DO 로 옮겨줬다 ㅎㅎ 완저니 성공~
    -(어려웠다고는 말 못해 .. 핡)

profile
기억력 안 좋은 FE 개발자의 메모장

0개의 댓글