⛏️
공부방
  • README.md
  • 프로젝트
    • ft_transcendence
      • 설계
        • 0. 프론트 디자인
        • 1. BackboneJS 뷰 객체
        • 2. API 설계
        • 3. 레일즈 라우팅 구현
        • 4. DB 설계
        • 5. 채널 설계
    • slab-saver
    • react-payment
  • 공부
    • HTML, CSS
      • GRID
      • emmet
      • position
      • CSS Unit
        • 단위 정리
        • 기준을 정해보자
        • em의 정확한 기준은 뭐야?
      • flex
      • NAVBAR 실습
      • 유튜브 화면 만들어보기
    • SQL
      • 이론
        • 1강 데이터베이스
        • 2강 다양한 데이터 베이스
        • 3강 데이터베이스 서버
      • 명령어
        • DB 관리
        • TABLE 관리
        • Constraints
        • SQL 명령어 - 1
        • SQL 명령어 - 2
        • SQL 명령어 - 3
        • SQL 명령어 - 4
        • SQL 명령어 - 5
    • Ruby
      • 루비 객체와 클래스
      • 곡괭이
        • Chapter2. Ruby.new
        • Chapter3. 클래스, 객체, 변수
        • Chapter4. 컨테이너, 블록, 반복자
        • Chapter5. 기능 공유하기
        • Chapter6. 표준 타입
        • Chapter8. 메서드 파헤치기
    • Python
      • 유용한 링크
    • RubyOnRails
      • 아직 정리하지 못한 것들
        • RSPEC 을 이용한 테스트 완전 자동화
        • 레일즈 이니셜라이징 과정
        • 액션케이블 구체적으로 정리하기
        • 웹팩으로 자바스크립트 모듈 관리하기
      • ACTIVE JOB
        • 액티브잡의 기본
        • 실전! 액티브 잡을 이용한 스케쥴링
        • 서버를 껏다 키면 스케쥴링 된 이벤트가 사라진다!
      • ACTION CABLE
        • 액션케이블 Consumer를 이용해서 문제 해결
        • 액션케이블 연결 순서
      • ACTIVE STORAGE
      • 모델
        • validation
          • seeds 데이터 validation 스킵
          • validation 검사가 save, update, create 모든 경우에 일어난다
          • validator 클래스
          • 커스텀Validation
          • validates format(정규표현식)
        • 액티브레코드 find의 다양한 활용
        • 한 레코드에 동시 접속 막자!! with_lock
        • 레일즈 where 사용법
        • 레일즈에서 모델 관련 이슈
        • 모델이름바꿀때명심할것
        • 모델의 includes 메서드
        • 연관 모델을 다른 이름으로 설정하고 가져오기
      • 기본 상식
        • form으로 전달되는 params를 분석해보자
        • StrongParameter 쿼리 배열 받기
        • view helper로 디버깅 하는 방법
        • css 파일을 수정했는데 적용이 안된다?
        • StrongParameter 일반데이터와 객체 데이터 한번에 받기
        • wrap-parameter body가 두 번씩 날라오는 이유
        • 컬렉션 map에서 요소 스킵하는법
        • CASE를 이용해서 정렬(일반적인 정렬 X)
        • 문자열(정규표현식)
        • TIME ZONE 설정하기
        • 커스텀exception
      • RSPEC으로 모델 테스트하기
      • 한 눈에 읽는 루비 온 레일즈
      • Perfect RubyOnRails
        • Chapter1. 소개
        • Chapter2. RubyOnRails 기본
        • Chapter3. 스캐폴딩
        • Chapter7. 라우팅
        • Chapter8. 테스트
    • Javascript
      • var, let, const 차이
      • 브라우저 동작 원리
      • 디바운싱과 쓰로틀링
      • Tagged Template Literal(styled-components)
      • IntersectionObserver 를 사용해서 스크롤 이벤트의 부하 줄여주기
      • EVENT LOOP
        • 자바스크립트에서 어떻게 비동기적인 실행이 가능한걸까?
        • 이벤트 루프의 동작
        • setTimeout이 실행되면 어떤 동작이 일어날까?
        • 블록은 실행이 보장된다
        • 콜스택에 있는 블록이 보장된다는 점을 이용해서 브라우저 죽이기
        • setTimeout 무한반복으로 브라우저는 죽을까?
        • Promise 무한반복으로는 브라우저를 죽일 수 있을까?
        • RAF는 그럼 뭐야?
      • forEach는 반복도중 멈출 방법이 throw 밖에 없다!
      • 임시
        • 정리할 것 목록
          • 자바스크립트 기본 문법
        • 이벤트 임시 정리
      • 유용한 링크
      • arrow function 을 이용한 bind 이슈 해결
      • preventDefault - passive
      • CRITICAL-RENDERING-PATH
      • setInterval에 클로져 개념 사용하기
      • 오디오 문제 이슈
      • 자바스크립트의 식과 문
        • 식과 문이란 무엇인가...
        • 식
          • 1. 기본값과 래퍼객체
          • 2. 참조값과 가비지컬렉팅
        • 식을 조금 더 자세히 알아보자
      • prototype, [[Prototype]] 차이
      • export, import 학습
      • ESlint
      • 아주아주기본
        • Chatper1. 기본
        • Chapter2. 타입
        • Chapter3. 연산자
        • Chapter4. 제어문
        • Chapter5. 배열
        • Chapter6. 함수
        • Chapter7-1. 객체
        • Chapter7-2. 객체
        • Chapter8. 표준객체
        • Chapter9. DOM
      • 이벤트 위임
      • 이벤트가 버블링 되서 root 까지 가다보면... 부모의 부모의 ... 모든 click 이벤트를 발동시키는거 아니야?
      • classList
    • BackboneJS
      • Backbone Model 프로토타입에 메서드 구현하기
      • BackboneJS의 각 요소의 역할과 책임을 확실히 이해하자
      • Window 이벤트를 listenTo로 감시하기
      • 뷰 자신이 자신을 지워야 할 때를 감지하려면 어떻게 해야하는가?
      • 백본 VIEW의 remove와 jquery의 remove 는 다르다!
      • 백본 컬렉션 URL에 쿼리 붙이기
      • index.html.erb와 BackboneJS의 결합
      • 백본 모델과 컬렉션에서 fetch 를 통해 JSON 가져오기!
      • 모델은 urlRoot, 컬렉션은 url
      • ISSUE
      • Absolute Beginner
        • Part1
        • Part2
        • Part3
        • Part4
    • 문제풀이
      • 01. 유효한 팰린드롬(leetcode: 125)
      • 02. 문자열 뒤집기(leetcode: 344)
      • 03. 로그파일 재정렬(leetcode 937)
      • 04. 가장 흔한 단어(leetcode: 819)
      • 05. 그룹 애너그램(leetcode: 49)
      • 06. 가장 긴 팰린드롬 문자열(leetcode: 5)
      • 07. 두 수의 합(leetcode: 1)
      • 08. 빗물 트래핑
      • 09. 세 수의 합(leetcode: 15)
    • BlackCoffeeStudy
      • level1
        • 1주차
    • express
      • Untitled
      • 구글 애널리틱스 연결하기
      • passport를 활용한 로그인
      • express-init 명령어 사용
      • ec2와 DBeaver
      • mariadb 설치
      • sequelize 설치 및 사용법
        • sequelize 설치
        • sequelize-cli 사용법
        • 모델 간 연관관계 맺기
        • Hook 사용하기
      • express-ejs-layout 활용하기
      • Bootstrap
      • npm install로 설치한 모듈 ejs에서 사용하기
      • 미들웨어
    • cypress
      • window.alert 테스트는 어떻게 하지?
      • 상수를 어디에 저장할건가?
      • before()와 beforeEach()
    • aws
      • aws로 프로젝트를 배포해보자!
      • nginx로 리버스프록시 서버를 만들자
      • github actions 로 푸쉬되면 자동으로 업데이트 하는 기능 만들어보기
    • react
      • Drag & Drop 를 이용해서 리스트 요소 순서 바꾸기
      • CRA에서 CRACO 사용하지 않고 절대경로 import(NODE_PATH)
      • useEffect내에서 state의 dependency 문제
      • IntersectionObserverAPI로 무한스크롤 구현
      • react-testing-library
        • 기본
        • react-router-dom 에서의 에러
        • event 발생시키기
        • Integration testing하기
        • async하게 렌더링 되는 요소 잡기
        • Mocking 하기
      • CRA로 만든 앱에서 절대경로로 import 해오기(alias하기)
      • 커스텀 훅 만들기
    • 타입스크립트
      • 조건부타입 (Conditional types)
      • Generics
      • Keyof 타입 오퍼레이터
      • Indexed Access Types
      • 타입 챌린지
        • easy
          • 00. Awaited
          • 01. Concat
          • 02. Exclude
          • 03. First Of Array
          • 04. If
          • 05. Includes
          • 06. Pick
          • 07. Readonly
          • 08. Length
          • 09. Tuple to Object
        • mediun
          • 01. Absolute
    • Firebase
      • 파이어스토어 규칙
    • 기타
      • 협업 프로세스
      • UUID
      • 구글애널리틱스 설치하기
      • 드림코딩 강의
        • 포트폴리오
          • CSS
            • nth-child
            • CSS 팁
          • 자바스크립트
            • 1. 스크롤에 따른 navbar 의 색 변경하기
            • 2. navbar 버튼을 누르면 해당 페이지로 스크롤링 되게 만들자
            • 3. 스크롤 다운 하면 arrow-up 버튼 나오게 하기
            • 4. project 필터링 구현
            • 5. project 필터링에 transition 효과 넣기
      • GIT
        • 기본 사용법 정리
        • git remote update - remote 브랜치 가져오기
  • 기타
    • 이것저것
      • 독서
        • 클린코드
          • Chapter0. 나는 왜 클린코드 책을 읽는가?
          • Chapter1. 클린코드
          • Chapter2. 의미있는 이름
          • Chapter3. 함수
          • Chapter4. 주석
          • Chapter5. 형식 맞추기
      • 용어
      • IDE
        • RubyMine
          • 실전이 중요!
          • 1. Editor Basic
          • 2. Navigation
          • 3. Completion
          • 4. Refactoring
          • 5. Code Assistance
      • MAC에서 살아남기
        • Alfred - Spotlight 업그레이드
        • Vimium
        • BetterTouchTool - 트랙패드
        • 구름 입력기 - ESC, `
        • Spectacle - 화면 분할
    • 원티드 프리온보딩
      • 1주차
        • 월요일
        • 목요일
      • 2주차
      • 3주차
      • 4주차
      • 5주차
      • 6주차
    • 일기장
      • 2020
        • December
          • 20201208(화)
          • 20201209(수)
          • 20201210(목)
          • 20201211(금)
          • 20201214(월)
          • 20201215(화)
          • 20201216(수)
          • 20201217(목)
          • 20201218(금)
          • 20201219(토)
          • 20201221(월)
          • 20201222(화)
          • 20201223(수)
          • 20201224(목)
          • 20201226(토)
          • 20201228(월)
          • 20201229(화)
          • 20201230(수)
          • 20201231(목)
      • 2021
        • January
          • 20210101(금)
          • 20210102(토)
          • 20210105(화)
          • 20210106(수)
          • 20210107(목)
          • 20210108(금)
          • 20210109(토)
          • 20210112(화)
          • 20210113(수)
          • 20210114(목)
          • 20210115(금)
          • 20210117(일)
          • 20210118(월)
          • 20210119(화)
          • 20210120(수)
          • 20210121(목)
          • 20210125(월)
          • 20210126(화)
          • 20210127(수)
          • 20210128(목)
          • 20210129(금)
        • February
          • 20210201(월)
          • 20210202(화)
          • 20210203(수)
          • 20210204(목)
          • 20210205(금)
          • 20210207(일)
          • 20210208(월)
          • 20210209(화)
          • 20210217(수)
          • 20210218(목)
          • 20210219(금)
          • 20210220(토)
          • 20210222(월)
          • 20210223(화)
          • 20210224(수)
          • 20210226(금)
          • 20210228(일)
        • March
          • 20210302(화)
          • 20210303(수)
          • 20210304(목)
          • 20210305(금)
          • 20210306(토)
          • 20210308(월)
          • 20210309(화)
          • 20210310(수)
          • 20210311(목)
          • 20210312(금)
          • 20210313(토)
          • 20210315(월)
          • 20210316(화)
          • 20210317(수)
          • 20210318(목)
          • 20210319(금)
          • 20210322(월)
          • 20210323(화)
          • 20210324(수)
          • 20210325(목)
          • 20210327(토)
          • 20210329(월)
          • 20210330(화)
          • 20210331(수)
        • April
          • 20210406(화)
          • 20210407(수)
          • 20210408(목)
          • 20210409(금)
          • 20210410(토)
          • 20210412(월)
          • 20210413(화)
          • 20210414(수)
          • 20210415(목)
          • 20210416(금)
          • 20210417(토)
          • 20210419(월)
          • 20210420(화)
          • 20210421(수)
          • 20210422(목)
        • July
          • 20210728(수)
Powered by GitBook
On this page
  • 인터페이스
  • DragEvent
  • DataTransfer
  • 실제 사용하기
  • 1. draggable 속성 넣기
  • 2. onDragStart 핸들러
  • 3. onDragOver 핸들러
  • 4. onDrop 핸들러

Was this helpful?

  1. 공부
  2. react

Drag & Drop 를 이용해서 리스트 요소 순서 바꾸기

PreviousreactNextCRA에서 CRACO 사용하지 않고 절대경로 import(NODE_PATH)

Last updated 3 years ago

Was this helpful?

todo list 를 구현했는데, 뭔가 너무 아쉬웠다. 평소에 구현해보고 싶었던 기술중에 Drag & Drop 이 있었는데 todo list 에 적용하기 너무 좋아보여서 시도했다.

인터페이스

DnD 의 인터페이스로는 크게 4가지가 존재한다.

DateEvet 와 DataTranfer 만 알아보자.

DragEvent

이벤트

이벤트 핸들러

설명

dragstart (en-US)

요소나 텍스트 블록을 드래그 할 때 발생한다.

dragend (en-US)

dragenter (en-US)

dragover (en-US)

요소나 텍스트 블록을 적합한 드롭 대상 위로 지나갈 때 발생한다. (매 수백 밀리초마다 발생한다.)

dragleave (en-US)

드래그하는 요소나 텍스트 블록이 적합한 드롭 대상에서 벗어났을 때 발생한다.

drop (en-US)

dragexit

요소가 더 이상 드래그의 직접적인 대상이 아닐 때 발생한다.

Drag 관련 이벤트. 여기서 중요한건 이벤트의 발동 주체가 2가지로 나뉜다는것임.

1. 드래그 요소

마우스로 클릭하고 끌고 다니는 요소

  • drag

  • dragStart

  • dragEnd

2. 드래그 요소와 겹치는 아이템

  • dragEnter

  • dragOver (필수로 구현)

  • dragLeave

  • drop (필수로 구현)

여기서 주목할 건 Drag 요소를 다른 요소 어딘가에 놓으면 그에 대한 이벤트는 drop 이 발생하고 이 drop 을 핸들링 하는 곳이 Drag 된 요소가 아니라 그 요소와 겹치는 아이템이라는 것.

여기서 의문이 생긴다. Drag 된 요소가 아니라 그 요소가 떨어진 곳에서 Drop 이벤트 핸들러를 실행한다면, Drag 된 요소의 정보는 어떻게 넘겨주는거지? 그 의문은 DataFransfer 에서 해결된다.

DataTransfer

get, set 이외에도 여러 메서드, 프로퍼티가 있다. 필요하면 위의 링크로 가서 보자.

실제로 드래그를 이용해서 리스트 요소의 순서를 바꾸는걸 생각해보자.

  1. 요소를 마우스로 잡는다.

    • 마우스로 잡은 요소에서 dragStart 이벤트를 핸들링한다.

  2. 끌고 다닌다.

  3. 원하는 곳에 내려놓는다.

    • 내려놓은 곳의 요소에서 drop 이벤트가 발동된다.

우리는 1번에서 요소에 대한 정보를 어딘가에 저장해야하고, 그 정보를 3번에서 이용해야한다. 이걸 해주는게 DataTransfer다. 사용법은 매우 간단하다. setData 를 통해 데이터를 저장하고, getData 를 이용해서 저장된 정보를 불러온다.

실제 사용은 아래처럼 하면된다.

...
// 1번. drag 요소의 데이터를 저장
const handleDragStart = (e) => {
  // key는 getData 에서 사용할 key
  // value 는 저장할 데이터
  e.dataTransfer.setData([key], [value]);
}

// 3번. 놓임 당한 곳에서 drag 된 요소 가져오기
const handleDrop = (e) => {
  e.dataTransfer.getData([key]);
  .. 추가 작업들...
}
...

localStorage 처럼 get, set 으로 사용하면 된다.

실제 사용하기

아래의 코드는 미래 재사용을 위해 useDragAndDrop 이라는 커스텀훅으로 만들었다.

1. draggable 속성 넣기

지금까지 내가 만든 웹요소들은 드래그가 모두 불가능했었다. 왜? 바로 draggable 속성을 넣지 않았기 때문이다. 즉 draggable 속성을 넣으면 요소들은 드래깅이 가능해진다.

...
return {
  <TodoItemContainer
      draggable
         ...
    >
}

draggable 속성을 넣음으로써 API 를 사용할 수 있게 된다.

2. onDragStart 핸들러

드래그의 시작을 알려준다. 인터페이스 부분에서 설명했다시피 이 부분에서 옮기는 요소에 대한 정보를 저장해야한다.

const handleDragStart = (e: React.DragEvent<HTMLDivElement>) => {
  setisDragging(true); // 1
  e.dataTransfer.effectAllowed = 'move'; // 2
  e.dataTransfer.setData('text/plain', id); // 3
};

코드를 분석해보자면

  1. setIsDragging

    • 현재 todo 가 드래그 하는 중이라는걸 알려주는 state 다.

    • 이 값을 통해 todo 는 자신이 드래깅중인지 또는 아닌지를 알 수 있다.

      • css 핸들링에 사용할 수 있다.

  2. e.dataTransfer.effectedAllowed = move

  3. e.dataTransfer.setData('text/plain', id);

    • 드래그 하는 요소의 정보를 담는다.

3. onDragOver 핸들러

Dropzone

tkdghk

const handleDragOver = (e: React.DragEvent<HTMLDivElement>) => {
  e.preventDefault(); // 1
  setIsDragOver(true); // 2
};
  1. e.preventDefault();

    • 기본으로 발동하는 다른 이벤트들을 막는다. (Touch, pointer events..)

  2. setIsDragOver(true);

    • 현재 요소가 드래그 요소의 아래 깔려있음을 말해준다.

4. onDrop 핸들러

Dropzone

const handleDrop = (e: React.DragEvent<HTMLDivElement>) => {
  e.preventDefault();
  setisDragging(false);
  setIsDragOver(false);
  const movingTarget = e.dataTransfer.getData('text/plain'); // 1
  callback(movingTarget, id); // 2
};
  1. const movingTarget = e.dataTransfer.getData('text/plain');

    • 이전에 저장한 데이터를 가져온다.

  2. callback()

    • todo 요소의 위치를 바꾸는 함수다.

사용자가 요소나 텍스트 블록을 드래그하기 시작했을 때 발생한다. (를 보시오.)

드래그를 끝냈을 때 발생한다. (마우스 버튼을 떼거나 ESC 키를 누를 때) (를 보시오)

드래그한 요소나 텍스트 블록을 적합한 드롭 대상위에 올라갔을 때 발생한다. (를 보시오.)

요소나 텍스트 블록을 적합한 드롭 대상에 드롭했을 때 발생한다. (를 보시오.)

드래그를 해보면 디폴트로 마우스 아래에 + 버튼이 생긴다. 이 버튼을 막아준다. .

MDN - HTML 드래그 앤 드롭 API
MDN - Drag Operations(실습)
HTML SPEC - Drag and drop
Codepan example
How to Implement Drag and Drop Feature for Your React Component
DragEvent
DataTransfer
DataTransferItem (en-US)
DataTransferItemList (en-US)
Define a drop zone
https://developer.mozilla.org/ko/docs/Web/API/DataTransfer
여기를 참고하자
todoList 내의 todo 들을 드래그해서 옮기는 코드를 예로 든다. 코드는 여기를 눌러서 확인하자.
https://developer.mozilla.org/en-US/docs/Web/API/HTML_Drag_and_Drop_API/Drag_operations#drageffects
ondragstart (en-US)
드래그 시작하기
drag
ondrag (en-US)
ondragend (en-US)
드래그 끝내기
ondragenter (en-US)
드롭 대상 지정하기
ondragover (en-US)
ondragleave (en-US)
ondrop (en-US)
드롭하기
ondragexit (en-US)