본 포스팅은 노마드코더의 React JS 마스터클래스를 수강한 뒤 작성되었습니다.
해당 함수는 argument로 多은 것들을 알려줌
//App.tsx의 일부
// 드래그가 끝났을때 실행되는 함수
const onDragEnd = () => {};
: 우리의 array를 재정렬할 수 있게 도와주는 역할
## 아래는 splice를 사용하여 array를 수정하는 예시
const x = [1,2,3]
## 이건 x 배열에서 1를 지우겠다는 의미
x.splice(0,1)
## x를 다시 확인해보면, x는 2개의 item만 有 [2,3]
x
현재까지 진행된 코드는 다음과 같다.
내가 원하는 요소를 끌어서 다른 위치에 두면 위치가 이동된다.
//App.tsx
import {
DragDropContext,
Droppable,
Draggable,
DropResult,
} from "react-beautiful-dnd";
import { useRecoilState } from "recoil";
import styled from "styled-components";
import { todoState } from "./atoms";
const toDos = ["a", "b", "c", "d", "e", "f"];
function App() {
const [toDos, setToDos] = useRecoilState(todoState);
// 드래그가 끝났을때 실행되는 함수
/*
toDos를 가지고 우리가 진행할 2가지 단계
1. array로부터 source.index(최근에 움직인 item의 index)를 지우기
2. destination의 index를 확인해서 해당 index에 우리가 방금 삭제한것을 추가하기
*/
const onDragEnd = ({ destination, source }: DropResult) => {
if (!destination) return;
setToDos((oldToDos) => {
const copyToDos = [...oldToDos];
// 1) source.index에서 item 삭제하기
//source.index에서는 우리에게 array에서 우리가 움직이고 싶은 item이 어디에 有는지 알려줌
copyToDos.splice(source.index, 1);
// 2) destination.index로 item을 다시 돌려주기
copyToDos.splice(destination?.index, 0, toDos[source.index]);
return copyToDos;
});
};
return (
<DragDropContext onDragEnd={onDragEnd}>
<Wrapper>
<Boards>
<Droppable droppableId="one">
{(magic) => (
<Board ref={magic.innerRef} {...magic.droppableProps}>
{toDos.map((toDo, index) => (
<Draggable key={toDo} draggableId={toDo} index={index}>
{(magic) => (
<Card
ref={magic.innerRef}
{...magic.dragHandleProps}
{...magic.draggableProps}
>
{toDo}
</Card>
)}
</Draggable>
))}
{magic.placeholder}
</Board>
)}
</Droppable>
</Boards>
</Wrapper>
</DragDropContext>
);
}
const Wrapper = styled.div`
display: flex;
max-width: 480px;
width: 100%;
margin: 0 auto;
justify-content: center;
align-items: center;
height: 100vh;
`;
const Boards = styled.div`
display: grid;
width: 100%;
grid-template-columns: repeat(1, 1fr);
`;
const Board = styled.div`
padding: 20px 10px;
padding-top: 30px;
background-color: ${(props) => props.theme.boardColor};
border-radius: 5px;
min-height: 200px;
`;
const Card = styled.div`
border-radius: 5px;
margin-bottom: 5px;
padding: 10px 10px;
background-color: ${(props) => props.theme.cardColor};
`;
export default App;
BUT 아직 문제가 有
-> 요소를 선택해서 다른 곳에 둘때, "가끔"씩 모든 요소들의 글자가 떨리는 현상이 발생! 이걸 이제 고쳐볼게
이유는 아래와 같아.
!! 부모 component들의 State가 바뀌기만 하면, 모든 것들이 새로고침되기 때문이야!!
∴ 내가 f 요소의 위치만 옮겨도, a~f까지의 모든 요소들이 불필요하게 rerendering되고 有!
: react.js에게 제발 이 component는 rendering하지 말라고 말하는 역할 수행 (if prop이 변하지 X는다면!)
// default 하고 함수이름을 쓰지 X고 React.memo라고 작성
// react에게 prop이 변하지 X았다면, DraggleCard를 다시 rendering 하지 X라고 말하는 것
export default React.memo(DraggableCard);
아래는 전체코드이다.
//DraggableCard.tsx
import React from "react";
import { Draggable } from "react-beautiful-dnd";
import styled from "styled-components";
interface IDragabbleCardProps {
toDo: string;
index: number;
}
function DraggableCard({ toDo, index }: IDragabbleCardProps) {
return (
<Draggable key={toDo} draggableId={toDo} index={index}>
{(magic) => (
<Card
ref={magic.innerRef}
{...magic.dragHandleProps}
{...magic.draggableProps}
>
{toDo}
</Card>
)}
</Draggable>
);
}
const Card = styled.div`
border-radius: 5px;
margin-bottom: 5px;
padding: 10px 10px;
background-color: ${(props) => props.theme.cardColor};
`;
export default React.memo(DraggableCard);
이렇게 이제 react.Memo를 사용하면, 내가 변화시킨 것들만 rendering이 다시 되는 것을 볼 수 有 😊😊😊
+) 만약 내가 e가 제일 아래에 有는데 제일 위로 보낸다면, a~e의 모든 요소들이 re rendering될거야!
∵ 모든 요소들의 index의 prop이 변경되니까