#7.4 - #7.7

Jisoo Shin·2023년 11월 13일
0

ReactJs마스터클래스

목록 보기
17/17
post-custom-banner

본 포스팅은 노마드코더의 React JS 마스터클래스를 수강한 뒤 작성되었습니다.

📌 onDragEnd 함수

해당 함수는 argument로 多은 것들을 알려줌

  • source에 있는 draggableIdindex 를 통해 우리가 드래그 한 것이 무엇인지를 알려줌
  • destination을 통해 해당 요소가 어디로 갔는지도 알 수 有
//App.tsx의 일부

  // 드래그가 끝났을때 실행되는 함수
  const onDragEnd = () => {};

📌 splice

: 우리의 array를 재정렬할 수 있게 도와주는 역할

  • 한 자리에서 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 Memo


📌 react memo

: 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이 변경되니까

post-custom-banner

0개의 댓글