저는 React -dnd , 유연한 HTML5 드래그 앤 드롭 믹스 인 인 React를 완전한 DOM 제어로 구현했습니다.
기존의 드래그 앤 드롭 라이브러리는 내 사용 사례에 맞지 않아서 직접 작성했습니다. Stampsy.com에서 약 1 년 동안 실행해온 코드와 비슷하지만 React와 Flux를 활용하기 위해 다시 작성되었습니다.
내가 가진 주요 요구 사항 :
- 자체의 DOM 또는 CSS를 내 보내지 않고 소비하는 구성 요소에 맡깁니다.
- 소비 구성 요소에 가능한 한 적은 구조를 적용하십시오.
- HTML5 드래그 앤 드롭을 기본 백엔드로 사용하되 나중에 다른 백엔드를 추가 할 수 있도록합니다.
- 원본 HTML5 API와 마찬가지로 "드래그 가능한 뷰"가 아니라 데이터 드래그를 강조합니다.
- 소비 코드에서 HTML5 API 특성을 숨 깁니다.
- 서로 다른 구성 요소는 서로 다른 종류의 데이터에 대한 "드래그 소스"또는 "드롭 대상"일 수 있습니다.
- 필요한 경우 하나의 구성 요소에 여러 드래그 소스 및 드롭 대상을 포함 할 수 있습니다.
- 호환되는 데이터를 끌거나 가져 가면 놓기 대상의 모양을 쉽게 변경할 수 있습니다.
- 요소 스크린 샷 대신 드래그 썸네일에 이미지를 사용하여 브라우저의 단점을 피하세요.
이것이 당신에게 익숙한 것처럼 들리면 계속 읽으십시오.
용법
단순 드래그 소스
먼저 드래그 할 수있는 데이터 유형을 선언합니다.
드래그 소스 및 드롭 대상의 "호환성"을 확인하는 데 사용됩니다.
module.exports = {
BLOCK: 'block',
IMAGE: 'image'
};
(여러 데이터 유형이없는 경우이 라이브러리가 적합하지 않을 수 있습니다.)
그런 다음 드래그 할 때 다음을 나타내는 매우 간단한 드래그 가능한 구성 요소를 만들어 보겠습니다 IMAGE
.
var { DragDropMixin } = require('react-dnd'),
ItemTypes = require('./ItemTypes');
var Image = React.createClass({
mixins: [DragDropMixin],
configureDragDrop(registerType) {
registerType(ItemTypes.IMAGE, {
dragSource: {
beginDrag() {
return {
item: this.props.image
};
}
}
});
},
render() {
return (
<img src={this.props.image.url}
{...this.dragSourceFor(ItemTypes.IMAGE)} />
);
}
);
를 지정 하여이 구성 요소의 끌어서 놓기 동작을 configureDragDrop
알려줍니다 DragDropMixin
. 드래그 가능한 컴포넌트와 드롭 가능한 컴포넌트 모두 동일한 믹스 인을 사용합니다.
내부는 configureDragDrop
, 우리는 호출 할 필요는 registerType
우리의 정의의 각 ItemTypes
구성 요소를 지원하는. 예를 들어 앱에 여러 이미지 표현이있을 수 있으며 각각은 dragSource
for ItemTypes.IMAGE
.
A dragSource
는 드래그 소스의 작동 방식을 지정하는 객체 일뿐입니다. beginDrag
드래그하는 데이터를 나타내는 항목을 반환하도록 구현해야 하며, 선택적으로 드래그 UI를 조정하는 몇 가지 옵션을 구현해야합니다. canDrag
드래그를 금지하거나 endDrag(didDrop)
드롭이 발생했거나 발생하지 않았을 때 일부 로직을 실행하도록 선택적으로 구현할 수 있습니다 . 그리고 공유 믹스 인이 생성되도록함으로써 컴포넌트간에이 로직을 공유 할 수 dragSource
있습니다.
마지막으로 드래그 핸들러를 연결 하려면의 {...this.dragSourceFor(itemType)}
일부 (하나 이상의) 요소 를 사용해야합니다 render
. 즉, 하나의 요소에 여러 "드래그 핸들"이있을 수 있으며 서로 다른 항목 유형에 해당 할 수도 있습니다. ( JSX Spread Attributes 구문에 익숙하지 않은 경우 확인하십시오).
단순 드롭 대상
s ImageBlock
의 드롭 대상 이 되고 싶다고 가정 해 보겠습니다 IMAGE
. 우리가 제공해야하는 것을 제외하고는 거의 동일합니다 구현 :registerType
dropTarget
var { DragDropMixin } = require('react-dnd'),
ItemTypes = require('./ItemTypes');
var ImageBlock = React.createClass({
mixins: [DragDropMixin],
configureDragDrop(registerType) {
registerType(ItemTypes.IMAGE, {
dropTarget: {
acceptDrop(image) {
DocumentActionCreators.setImage(this.props.blockId, image);
}
}
});
},
render() {
return (
<div {...this.dropTargetFor(ItemTypes.IMAGE)}>
{this.props.image &&
<img src={this.props.image.url} />
}
</div>
);
}
);
드래그 소스 + 하나의 컴포넌트에 드롭 타겟
이제 사용자가에서 이미지를 드래그 할 수 있기를 원한다고 가정 해 보겠습니다 ImageBlock
. 적절한 파일 dragSource
과 몇 가지 핸들러 만 추가하면됩니다 .
var { DragDropMixin } = require('react-dnd'),
ItemTypes = require('./ItemTypes');
var ImageBlock = React.createClass({
mixins: [DragDropMixin],
configureDragDrop(registerType) {
registerType(ItemTypes.IMAGE, {
dragSource: {
canDrag() {
return !!this.props.image;
},
beginDrag() {
return {
item: this.props.image
};
}
}
dropTarget: {
acceptDrop(image) {
DocumentActionCreators.setImage(this.props.blockId, image);
}
}
});
},
render() {
return (
<div {...this.dropTargetFor(ItemTypes.IMAGE)}>
{/* Add {...this.dragSourceFor} handlers to a nested node */}
{this.props.image &&
<img src={this.props.image.url}
{...this.dragSourceFor(ItemTypes.IMAGE)} />
}
</div>
);
}
);
다른 무엇이 가능합니까?
모든 것을 다루지는 않았지만 몇 가지 방법으로이 API를 사용할 수 있습니다.
- 및를 사용
getDragState(type)
하여 getDropState(type)
드래그가 활성 상태인지 알아보고 CSS 클래스 또는 속성을 전환하는 데 사용합니다.
- 이미지를 끌기 자리 표시 자로 사용하도록 지정
dragPreview
합니다 Image
(이미지 ImagePreloaderMixin
를로드하는 데 사용).
ImageBlocks
재정렬 가능 하게 만들고 싶습니다 . 우리는 그들을 구현해야 dropTarget
하고 dragSource
위해 ItemTypes.BLOCK
.
- 다른 종류의 블록을 추가한다고 가정합니다. 믹스 인에 배치하여 재정렬 로직을 재사용 할 수 있습니다.
dropTargetFor(...types)
한 번에 여러 유형을 지정할 수 있으므로 하나의 드롭 영역에서 여러 유형을 포착 할 수 있습니다.
- 보다 세밀한 제어가 필요한 경우 대부분의 메서드는 마지막 매개 변수로 발생하는 드래그 이벤트를 전달합니다.
최신 문서 및 설치 지침 은 Github의 react-dnd 저장소로 이동 하세요.