我正在构建一个应用程序,该应用程序需要对项目表进行排序并根据它们的排序更改它们的 orderNumber。我安装并使用了一个名为 react-dnd 的库来处理排序/排序的功能,到目前为止它工作得很好。我遇到的问题是更新。当用户移动其中一项时,我需要向 api 发送 PUT 请求并更新其 orderNumber。昨晚工作得很好,这是我的代码。
ListItem(正在排序和更新的项目):
import React, {PropTypes} from 'react';
import {Link} from 'react-router';
import {DragSource, DropTarget} from 'react-dnd';
import sdk from '../../js/sdk';
import ItemTypes from './ItemTypes';
const itemSource = {
beginDrag(props) {
return {id: props.id};
}
};
const itemTarget = {
hover(props, monitor) {
const draggedId = monitor.getItem().id;
if (draggedId !== props.id) {
props.swapItems(draggedId, props.id);
}
}
};
const DragSourceDecorator = DragSource(ItemTypes.ITEM, itemSource, (connect, monitor) => {
return {
connectDragSource: connect.dragSource(),
isDragging: monitor.isDragging(),
};
});
const DropTargetDecorator = DropTarget(ItemTypes.ITEM, itemTarget, (connect) => {
return {connectDropTarget: connect.dropTarget()};
});
class SwagBagItem extends React.Component {
constructor(props) {
super(props);
this._handleDelete = this._handleDelete.bind(this);
}
componentWillReceiveProps(nextProps) {
const swagbagItemCpy = Object.assign({}, nextProps.swagbagItem);
delete swagbagItemCpy.id;
if (nextProps) {
sdk.put(`swagbags/${nextProps.swagbag.id}/items/${nextProps.swagbagItem.id}`, swagbagItemCpy)
.done((result) => {
console.log(result);
}).fail((error) => {
console.log(error);
})
;
}
}
_handleDelete(event) {
event.preventDefault();
event.stopPropagation();
if (confirm('Are you sure you want to delete this Swagbag Item?')) {
sdk.delete(`swagbags/${this.props.swagbag.id}/items/${this.props.swagbagItem.id}`)
.done(() => {
console.log('Swagbag Item remove!');
}).then(() => {
this.props.loadSwagBags();
});
}
}
render() {
const {swagbagItem} = this.props;
return this.props.connectDragSource(this.props.connectDropTarget(
<tr className="swagbag-item">
<td>{swagbagItem.id}</td>
<td><Link to={`${this.props.swagbag.id}/items/${swagbagItem.id}`}>{swagbagItem.name}</Link></td>
<td>{swagbagItem.uri}</td>
<td>
<div className="btn-group btn-group-xs pull-right" role="group">
<Link to={`${this.props.swagbag.id}/items/${swagbagItem.id}/edit`} className="btn btn-info">Edit</Link>
<Link to={`${this.props.swagbag.id}/items/${swagbagItem.id}`} className="btn btn-info">View</Link>
<button className="btn btn-danger btn-xs" onClick={this._handleDelete}>Remove</button>
</div>
</td>
</tr>
));
}
}
SwagBagItem.propTypes = {
loadSwagBags: PropTypes.func,
params: PropTypes.object,
swagbag: PropTypes.object,
swagbagItem: PropTypes.object,
};
export default DropTargetDecorator(DragSourceDecorator(SwagBagItem));
包含这些项目的容器或列表:
import React, {PropTypes} from 'react';
import {Link} from 'react-router';
import {DragDropContext} from 'react-dnd';
import HTML5Backend from 'react-dnd-html5-backend';
import sdk from '../../js/sdk';
import Nav from '../Nav';
import SwagBagItem from '../SwagBagItem';
class SwagBagItemsList extends React.Component {
constructor(props) {
super(props);
this.state = {
swagbag: null,
swagbagItems: [],
};
this._loadSwagBags = this._loadSwagBags.bind(this);
this._compareItems = this._compareItems.bind(this);
this._swapItems = this._swapItems.bind(this);
}
componentWillMount() {
this._loadSwagBags();
}
_compareItems(item1, item2) {
return item1.orderNumber - item2.orderNumber;
}
_swapItems(itemNo1, itemNo2) {
const items = this.state.swagbagItems;
let item1 = items.filter(item => item.id === itemNo1)[0];
let item2 = items.filter(item => item.id === itemNo2)[0];
let item1Order = item1.orderNumber;
item1.orderNumber = item2.orderNumber;
item2.orderNumber = item1Order;
items.sort(this._compareItems);
this.setState({swagbagItems: items});
}
_loadSwagBags() {
sdk.getJSON(`swagbags/${this.props.params.id}`)
.done((result) => {
this.setState({swagbag: result});
})
.then(() => {
sdk.getJSON(`swagbags/${this.props.params.id}/items?fields=id,name,summary,uri,itemImageFile,orderNumber`).done((results) => {
this.setState({swagbagItems: results});
});
});
}
render() {
let swagbagItems = null;
if (this.state.swagbagItems) {
swagbagItems = this.state.swagbagItems.map((item) => {
return <SwagBagItem
loadSwagBags={this._loadSwagBags}
swagbag={this.state.swagbag}
swagbagItem={item}
key={item.id}
id={item.id}
swapItems={this._swapItems}
/>;
});
}
if (!this.state.swagbag) {
return <div>Loading...</div>;
}
return (
<div>
<h1>Swagbag Items</h1>
<Nav swagbag={this.state.swagbag} />
<table className="table">
<thead>
<tr>
<th>id</th>
<th>name</th>
<th>uri</th>
<th></th>
</tr>
</thead>
<tbody>
{swagbagItems}
</tbody>
</table>
<Link to={`swagbags/createItem/swagbagid/${this.state.swagbag.id}`} className="btn btn-success">Add Item</Link>
</div>
);
}
}
SwagBagItemsList.propTypes = {
params: PropTypes.object,
};
export default DragDropContext(HTML5Backend)(SwagBagItemsList);
它正在发出 PUT 请求,但它只移动一个对象就连续发出数百个请求。我不能为我的生活弄清楚为什么。这会严重滞后应用程序并使其无响应。我是否以正确的方式解决这个问题,如果是这样,解决方案是什么?
编辑#1:今天醒来,应用程序运行良好。不幸的是,这正在生产中,所以在此之前我必须重新创建 800+ PUT 请求的错误并解决它。可能会为此提供赏金。