프론트엔드 데브코스 5기 TIL 27 - drag&drop/낙관적 업데이트와 작업 큐

김영현·2023년 11월 2일
1

TIL

목록 보기
31/129

드래그와 드롭

draggable

요소에 draggable=true를 주면 드래그가 가능해진다.


잠깐 했을뿐인데 굉장히 많은 이벤트가 발생했다.
아마 마우스관련 거의 모든 이벤트가 총망라 되어있지 않을까?
mousedown => mousemove...enter...out... => mouseup 이런식으로 진행될것 같다.

droppable

요소에 droppable을 주면 드래그한 다른 요소를 드롭해둘수 있다.
단, dragover, drop이벤트의 동작을 preventDefault()로 막아야 제대로 작동한다.
(html은 기본적으로 드롭이벤트를 막아놓는다)

또한 e.dataTransfer.dropEffect로 드래그할때 커서모양을 바꿔줄수도 있다.
move, copy, link가 있다.

데이터 전달

e.dataTransfer.setData(format, data)로 드래그할때 넣어줄 데이터를 전달할수 있고
e.dataTrasnfer.getData(format)으로 저장된 데이터를 가져올 수 있다!


낙관적 업데이트와 작업 큐

  const optimisticUpdateTodo = (todoId, isCompleted) => {
    const nextTodos = [...this.state.todos];
    const todoIndex = nextTodos.findIndex((todo) => todo._id === todoId);
    nextTodos[todoIndex].isCompleted = isCompleted;
    this.setState({
      ...this.state,
      todos: nextTodos,
    });
  };

이런식으로 상태만 먼저 업데이트 해주고, fetching은 나중에 한닷!
나중에 fetching할 작업들을 모아두는 를 따로 만들어서 실행해보자.
마치 브라우저의 태스크 큐와 같구나!

export default function TaskQueue() {
  this.task = [];

  this.addTask = (task) => {
    this.task.push(task);
  };
  this.run = () => {
    if (this.task.length) {
      const task = this.task.shift();
      task();
      this.run();
    }
  };
  this.hasTask = () => this.task.length > 0;
}

작업을 모아두고 UI작업이 바쁘지않을때 작업(fetch...등)을 실행한다.
이렇게 최적화를 하는구먼?
다만 언제 어떻게 동기화를 해줄지가 관건이다.
requestidleCallback이라는 메소드도 있다. 마치 requestAnimationFrames의 기능과 반대구나

아니면 아예 this.run내부에 reuqest를 불러서 사용해도 된다.

  this.removeTask = (urlPateern) => {
    tasks = tasks.filter((task) => !task.url.includes(urlPateern));
  };
  this.run = async () => {
    if (tasks.length) {
      const task = tasks.shift();
      await request(task.url, {
        method: task.method || "GET",
      });
      this.run();
    }
  };

이렇게 사용했을때 장점은 뭘까?

  1. todoList를 계속 위아래로 이동하다가 결국 삭제했을땐, 삭제작업만 넘겨주면 된다.(통신비용 최소화 및 렌더링 비용 최소화)
  2. UI작업이 바쁘지않을때 fetch를 넘겨줄 수 있음(최적화)
  3. 작업들을 한군데 모아 관리하기 편하다!

하지만 단점도 있다고 생각한다.

  1. 잘못 관리하면 업데이트가 전혀 되지 않을수 있다.(예외처리를 잘 해야함. 화면 나갈때나 팅길때...)
  2. 간단한 작업인데도 복잡해질 수 있다.

뭐든 장-단점은 존재한다. 적재적소에 사용할줄 아는 것이 좋은 개발자의 소양!


바닐라JS 강의를 마치며...

라이브러이없이 JS만으로 웹앱을 만들기란 쉽지 않으면서도 쉬웠다!
실제 업무환경에서는 이런 일이 드물지만 알면 굉장히 좋다.
=> 당연하다. 모든 프레임워크의 기반은 결국 JS다!
프레임워크나 라이브러리의 이해력을 키워준다.
=> 결국 JS를 제대로 이해하려면 CS지식이 필요하다! 이웅모저자님의 바텀 업방식이 떠오른다.

또한 화면을 컴포넌트단위로 생각하는 능력이 늘었다. 확장이 용이하고 버그를 덜 만드는 방식!
상태중심으로 화면의 변화를 표현하면, 상태만 관리하면 되기에 훨씬 편해졌다!


느낀점

CS는 아주 기본이디 기본이되 필수라고 다시한번 느낀다!
최적화는 결국 컴퓨터 사이언스를 바탕으로 행해진다.
예를들어 작업 큐를 직접 구현하려면 브라우저의 동작 원리도 알아야하며 자료구조도 알아야 하고 병렬적 처리
결국 공유자원을 사용하는 것이기에 운영체제에서 배운 프로세스간 동시성 문제도 생길 수 있다.

강의 자체의 내용은 좋았다. 중간중간 오타나 까먹어서 나는 버그들이 굉장히 인간적이었는데 편집하지 않고 그대로 보여주셔서 좋았다!
다만 생성자함수들의 겹치는 기능을 추상화하는 형식이라던가...
객체지향적으로 코딩하는 방법은 우리의 몫인 것 같다. 조금이라도 관련 파트가 있었으면 하는 아쉬움이 있다.

profile
모르는 것을 모른다고 하기

0개의 댓글