React DnD is a set of React higher-order components to help you build complex drag and drop interfaces while keeping your components decoupled. It is a perfect fit for apps like Trello and Storify, where dragging transfers data between different parts of the application, and the components change their appearance and the application state in response to the drag and drop events.
npm install --save react-dnd
You can also grab the standalone build from the repo's dist
folder.
// Let's make <Card text='Write the docs' /> draggable!
var React = require('react');
var DragSource = require('react-dnd').DragSource;
var ItemTypes = require('./Constants').ItemTypes;
var PropTypes = React.PropTypes;
/**
* Implements the drag source contract.
*/
var cardSource = {
beginDrag: function (props) {
return {
text: props.text
};
}
}
/**
* Specifies the props to inject into your component.
*/
function collect(connect, monitor) {
return {
connectDragSource: connect.dragSource(),
isDragging: monitor.isDragging()
};
}
var Card = React.createClass({
propTypes: {
text: PropTypes.string.isRequired,
// Injected by React DnD:
isDragging: PropTypes.bool.isRequired,
connectDragSource: PropTypes.func.isRequired
},
render: function () {
var isDragging = this.props.isDragging;
var connectDragSource = this.props.connectDragSource;
var text = this.props.text;
return connectDragSource(
<div style={{ opacity: isDragging ? 0.5 : 1 }}>
{text}
</div>
);
}
});
// Export the wrapped component:
module.exports = DragSource(ItemTypes.CARD, cardSource, collect)(Card);
Instead of providing readymade widgets, React DnD wraps your components and injects props into them. If you use React Router or Flummox, you already know this pattern.
React DnD fully embraces the declarative rendering paradigm of React and doesn't mutate the DOM. It is a great complement to Flux and other architectures with the unidirectional data flow. In fact it is built on Flux.
HTML5 drag and drop has an awkward API full of pitfalls and browser inconsistencies. React DnD handles them internally for you, so you can focus on developing your application instead of working around the browser bugs.
React DnD uses the HTML5 drag and drop under the hood, but it also lets you supply a custom “backend”. You can create a custom DnD backend based on the touch events, the mouse events, or something else entirely. For example, a built-in simulation backend lets you test drag and drop interaction of your components in a Node environment.
React DnD does not export mixins, and works equally great with any components, whether they are created using ES6 classes, createClass
or alternative React frameworks such as Omniscient. Its API shines with ES7 decorators if you like to be on the bleeding edge, but it also feels natural in both ES5 and ES6.
React DnD does not work on mobile browsers yet because it currently relies on the HTML5 drag and drop API which no mobile browsers implement. However, because React DnD is extensible, it is possible to add touch support using a custom backend with about 200 lines of code. This is currently a proof of concept, but any contributions in this direction are welcome. Touch support will be a priority for the upcoming 1.x releases.
React DnD gives you a set of powerful primitives, but it does not contain any readymade components. It's lower level than jQuery UI or interact.js and is focused on getting the drag and drop interaction right, leaving its visual aspects such as axis constraints or snapping to you. For example, React DnD doesn't plan to provide a Sortable
component. Instead it makes it easy for you to build your own, with any rendering customizations that you need.
Issues and potential improvements are discussed on Github.
The Gitter room is another good place to get support.
React DnD is licensed as MIT. Use it as you will.