프론트엔드 데브코스 TIL #DAY33

에구마·2023년 11월 2일
2

📚 23.11.02

  • Drag & Drop
  • 큐를 이용한 API 처리

Drag & Drop

요소의 속성으로 draggable="true" 값을 주면 요소의 드래그앤드롭 이벤트 발생이 가능하다.

드래그앤드롭시 발생하는 이벤트 중 이번에 사용한 이벤트는 다음과 같다

dragstart : 드래그 이벤트가 시작될 때 발생
dragover : 드래그 하는 중일 때 발생한다.
drop : 드래그가 끝나면 발생한다. e.preventDefault()와 함께 써야함!

dataTransfer

drag이벤트를 콘솔로 찍어보면 dataTransfer라는 객체를 볼 수 있다.


DataTransfer.dropEffect
현재 선택된 드래그 앤 드롭 작업의 타입을 가져오거나 작업을 새로운 타입으로 설정합니다.
값은 none, copy, link , move

e.dataTransfer.setData(포맷 문자열, 값)
e.dataTransfer.getData(포맷 문자열)

코드 예시와 함께 정리하기!

  $todoList.addEventListener("dragstart", (e) => {
    const $li = e.target.closest("li");
    e.dataTransfer.setData("todoId", $li.dataset.id);
  }); /// 'dragstart'가 일어나면, 해당 이벤트가 걸린 요소의 data-id값으로 setData합니다

  $todoList.addEventListener("dragover", (e) => {
    e.preventDefault(); // 필요!
    e.dataTransfer.dropEffect = "move";
  }); /// 

  $todoList.addEventListener("drop", (e) => {
    e.preventDefault();
    const droppedTodoId = e.dataTransfer.getData("todoId");
    /// 'drop'이 일어나면 dataTransfer에 저장해두었던 데이터값을 가져옵니다.
    const { todos } = this.state;
    if (!todos.find((todo) => todo.id === droppedTodoId)) {
      onDrop(droppedTodoId);
    }
  });

서버 패치 최적화

매 변경마다 서버에 패치하는 것은 불필요하고 서버 부담도 크다!
이 때 해결하는 방법,
1. 디바운스
2. 큐를 이용한 패치

호출할 서버패치 함수를 대기열(큐)에 담아두었다가 특정 버튼클릭 혹은 호출이 있을 때 큐에서 꺼내면서 실행한다.

여기에도 두가지 방법이 있다!
1) fetch요청 함수를 큐에 담는다. 작업 실행 시 큐에 담긴 함수들을 꺼내어 호출한다.

// 큐에 담는 로직
tasks.addTask(async () => {
  await request(`/${todoId}/toggle`, {
    method: "PUT",
  });
});
// 큐에서 꺼내며 실행하는 로직
export default function TaskQueue() {
  const tasks = [];

  this.addTask = (task) => {
    tasks.push(task);
    console.log(tasks); //아래 캡쳐
  };

  this.run = async () => {
    if (tasks.length > 0) {
      const task = tasks.shift();
      await task();
      this.run();
    }
  };

  this.hasTask = () => tasks.length > 0;
}

큐에 담긴 요소들은 다음과 같이 실행할 함수이다!

2) fetch요청할 데이터를 큐에 담는다. 작업 실행 시 큐에 담긴 데이터를 꺼내어 fetch작업에 담아 실행한다.

// 큐에 담는 로직
tasks.addTask({
    url: `/${todoId}/toggle`,
    method: "PUT",
  });
// 큐에 꺼내어 Fetch요청하는 로직
import { request } from "./api.js";

export default function SyncTasksManager() {
  const tasks = [];

  this.addTask = (task) => {
    tasks.push(task);
    console.log(tasks); // 아래 캡쳐
  };

  this.run = async () => {
    if (tasks.length > 0) {
      const task = tasks.shift();

      await request(task.url, {
        method: task.method || "GET",
      });

      this.run();
    }
  };
}

큐에 담긴 요소들은 다음과 같이 fetch요청에 대한 정보들이다.


객체를 key값으로 정렬

const obj = {
    a:4, d:2, z:3,b:1
};

// key로 오름차순 정렬
const sortedObj = Object.fromEntries(
    Object.entries(obj).sort(([a],[b]) => a < b? -1: 1 )
);

console.log(obj) //Object { a: 4, d: 2, z: 3, b: 1 }

console.log(sortedObj) // Object { a: 4, b: 1, d: 2, z: 3 }

참고 : 객체 정렬


배열 슬라이싱

array.splice()

배열의 기존 요소를 삭제 또는 교체하거나 새 요소를 추가하여 배열의 내용을 변경합니다

실행을 통해 본 배열 자체를 바꿔버린다. 변경(삭제)된 요소들을 담은 배열을 리턴합니다!!!!!!!

array.splice(start[, deleteCount[, item1[, item2[, ...]]]])
  • start: 변경할 부분 시작 인덱스
  • deleteCount : 변경할 갯수
  • item1,2,.. 추가할 요소들
const months = ['Jan', 'March', 'April', 'June'];

months.splice(2,1)
console.log(months) // Array ["Jan", "March", "June"]

months.splice(1, 0, 'Feb'); // deleteCount가 0 이면 아무것도 삭제하지않는다
console.log(months); // Array ["Jan", "Feb", "March", "April", "June"]

console.log(months.splice(4, 1, 'May')) // Array ["June"] //삭제한 배열을 리턴함!

console.log(months); // Array ["Jan", "Feb", "March", "April", "May"]

array.slice()

배열의 begin 부터 end 까지(end 미포함)에 대한 얕은 복사본을 새로운 배열 객체로 반환합니다.

원본 배열은 바뀌지 않습니다.

arr.slice([begin[, end]])
array.splice(start[, deleteCount[, item1[, item2[, ...]]]])
  • start: 변경할 부분 시작 인덱스
  • deleteCount : 변경할 갯수
  • item1,2,.. 추가할 요소들
const animals = ['ant', 'bison', 'camel', 'duck', 'elephant'];

console.log(animals.slice(2)); // Array ["camel", "duck", "elephant"]

console.log(animals.slice(2, 4)); // Array ["camel", "duck"]

console.log(animals.slice(-2)); // Array ["duck", "elephant"]

console.log(animals.slice(2, -1)); // Array ["camel", "duck"]

console.log(animals.slice()); // 전체복사
// : Array ["ant", "bison", "camel", "duck", "elephant"]



🫨 느낀 점

최적화는 끝도 없다 - ! 네트워크가 느릴 경우 화면에 나타나는 UI도 고려해야하고, 무언가 변경사항이 생겼을 때 서버에 요청을 주는 빈도도 고려해야한다. 위의 패치 최적화에 이어 대기열(큐)에 중복된 요소에 대한 요청을 지우는 작업도 했는데, 당연한데 놓치고 있던 부분이라고 생각이 들었다. 이런게 최적화구나🤩 앞으로의 프로젝트에서도 꼭 써야지




🤔 오늘 회고

Keep

오늘 첫 딥다이브발표가 있었다. 한달 반 지내온 회고 형식의 발표였는데, 발표자료에 내가 많이 등장했다 (ㅋ).. 슬랙챗에 이것저것 물어보고 또 물어봤었던 나를 발견했다... 처음엔 꽤 망설였는데, 결국 물어봤을 때 같은 고민을 하고 있는 사람도 있다는 것, 내 질문덕에 무심코 넘겼던 사람도 다시 깊게 고민해볼 수 있는 것 등을 느끼면서 이젠 일단 물어본다. 매니저님께도 칭찬들은 부분이니 아주 잘하고 있는것 같다 :)

Problem

발표를 들으며 '나는 저렇게 무언가 큰 변화가 있었나?'라는 생각을 하게 되었다. 돌이켜보면 많이 바뀌고 달라진거 같으면서도 엄청난 동기부여가 생기고 전환점을 가졌는지는.. 모르겠다. 문득 지금까지 미뤄온것들에 대해 생각이 났다..

Try

커피챗을 하면서 면접에 대해 팁도 얻었고 그외에 공부하면 좋을 것들, 유용한 링크들 등 도움을 많이 받았다. 또 그동안 슬랙에 꽤 쌓였던 질문들에 답을 얻었다. 그럼 이제 이걸 보자! 봐라!

profile
코딩하는 고구마 🍠 Life begins at the end of your comfort zone

0개의 댓글