react dnd demo2
import React, { Component } from 'react';
import './App.css';
import Card from './Card';
import HTML5Backend from 'react-dnd-html5-backend'
import { DragDropContext } from 'react-dnd'
// const update = require('immutability-helper');
import update from 'react-addons-update';
class App extends Component {
state = {
cards: [
{
id: 1,
text: 'Write a cool JS library',
},
{
id: 2,
text: 'Make it generic enough',
},
{
id: 3,
text: 'Write README',
},
{
id: 4,
text: 'Create some examples',
},
{
id: 5,
text:
'Spam in Twitter and IRC to promote it (note that this element is taller than the others)',
},
{
id: 6,
text: '???',
},
{
id: 7,
text: 'PROFIT',
},
],
}
deleteItem = id => {
this.setState(prevState => {
return {
items: prevState.items.filter(item => item.id !== id)
}
})
}
moveCard = (dragIndex, hoverIndex) => {
const { cards } = this.state
const dragCard = cards[dragIndex]
this.setState(
update(this.state, {
cards: {
$splice: [[dragIndex, 1], [hoverIndex, 0, dragCard]],
},
}),
() => {
console.log(this.state.cards);
})
}
render() {
return (
<div className="App">
<header className="App-header">
{/* <img src={logo} className="App-logo" alt="logo" /> */}
<h1 className="App-title">Welcome to React</h1>
</header>
<div className="App-intro">
<div className="app-container">
<div className="item-container">
{/* {this.state.items.map((item, index) => (
<Item key={item.id} item={item} handleDrop={(id) => this.deleteItem(id)} />
))} */}
</div>
{/* <Target /> */}
</div>
<div className="card-container">
{this.state.cards.map((card, i) => (
<Card
key={card.id}
index={i}
id={card.id}
text={card.text}
moveCard={this.moveCard}
/>
))}
</div>
</div>
</div>
);
}
}
export default DragDropContext(HTML5Backend)(App);
card
import React from 'react'; import PropTypes from 'prop-types'; import { findDOMNode } from 'react-dom'; import { DragSource, DropTarget, ConnectDropTarget, ConnectDragSource, DropTargetMonitor, DropTargetConnector, DragSourceConnector, DragSourceMonitor, } from 'react-dnd'; import { XYCoord } from 'dnd-core'; import flow from 'lodash/flow'; const style = { border: '1px dashed gray', padding: '0.5rem 1rem', marginBottom: '.5rem', backgroundColor: 'white', cursor: 'move', }; const cardSource = { beginDrag(props) { return { id: props.id, index: props.index, } }, }; const cardTarget = { hover(props, monitor, component) { const dragIndex = monitor.getItem().index const hoverIndex = props.index // Don't replace items with themselves if (dragIndex === hoverIndex) { return; } // Determine rectangle on screen const hoverBoundingRect = (findDOMNode( component, )).getBoundingClientRect(); // Get vertical middle const hoverMiddleY = (hoverBoundingRect.bottom - hoverBoundingRect.top) / 2; // Determine mouse position const clientOffset = monitor.getClientOffset(); // Get pixels to the top const hoverClientY = (clientOffset).y - hoverBoundingRect.top; // Only perform the move when the mouse has crossed half of the items height // When dragging downwards, only move when the cursor is below 50% // When dragging upwards, only move when the cursor is above 50% // Dragging downwards if (dragIndex < hoverIndex && hoverClientY < hoverMiddleY) { return; } // Dragging upwards if (dragIndex > hoverIndex && hoverClientY > hoverMiddleY) { return; } // Time to actually perform the action props.moveCard(dragIndex, hoverIndex); // Note: we're mutating the monitor item here! // Generally it's better to avoid mutations, // but it's good here for the sake of performance // to avoid expensive index searches. monitor.getItem().index = hoverIndex; }, } class Card extends React.Component { static propTypes = { connectDragSource: PropTypes.func.isRequired, connectDropTarget: PropTypes.func.isRequired, index: PropTypes.number.isRequired, isDragging: PropTypes.bool.isRequired, id: PropTypes.any.isRequired, text: PropTypes.string.isRequired, moveCard: PropTypes.func.isRequired, } render() { const { text, isDragging, connectDragSource, connectDropTarget, } = this.props; const opacity = isDragging ? 0 : 1; return ( connectDragSource && connectDropTarget && connectDragSource( connectDropTarget(<div style={{ ...style, opacity }}>{text}</div>), ) ); } } export default flow( DragSource( 'card', cardSource, (connect, monitor) => ({ connectDragSource: connect.dragSource(), isDragging: monitor.isDragging(), }), ), DropTarget('card', cardTarget, (connect) => ({ connectDropTarget: connect.dropTarget(), })) )(Card);

浙公网安备 33010602011771号