引言
项目开发中,特别是后台数据管理端,经常需要用到数据列表拖拽排序的需求,又不需要改变原有的数据结构与布局的情况下,使用高阶组件无疑是最好的选择,接下来于小伙伴们分享一下个人经验:
首先咱们给予
react-beautiful-dnd
插件环境下
yarn add react-beautiful-dnd
实践是检验真理的唯一标准
import { DragDropContext, Droppable, Draggable } from 'react-beautiful-dnd';
<DragDropContext onDragEnd={this.onDragEnd}>
<Droppable droppableId="droppable">
{(provided, snapshot) => (
<div ref={provided.innerRef}
style={this.getListStyle(snapshot.isDraggingOver)} // 返回添加配置的样式
{...provided.droppableProps}>
{this.state.children_list.map((item, index) => { // children_list 父组件传递过来的Element
if (React.isValidElement(item)) { // 判断是否是ReactNode节点
return (
<Draggable key={index} draggableId={`item-${index}`} index={index}>
{(provided, snapshot) => (
<div
ref={provided.innerRef}
{...provided.draggableProps}
{...provided.dragHandleProps}
style={getItemStyle(snapshot.isDragging, provided.draggableProps.style)}// 需要处理判断进行的样式返回
>
{item}
</div>
)}
</Draggable>
);
}
return item;
})}
</div>
)}
</Droppable>
</DragDropContext>
由于组件拖拽排序触发返回新的Element,需要拿去并渲染最新的ReactNode节点
componentDidUpdate(prevProps) {
if (!_.isEqual(prevProps.children, this.props.children)) {
this.setState({ children_list: this.props.children });
}
}
用于处理判断的返回样式函数
const getItemStyle = (isDragging, draggableStyle) => ({
userSelect: 'none',
...draggableStyle
});
拖拽触发后重新修改并返回数组数据
reorder = (list, startIndex, endIndex) => {
const result = Array.from(list);
const [removed] = result.splice(startIndex, 1);
result.splice(endIndex, 0, removed);
return result;
};
重要的来了:数据触发排序结束后回调返回当前的数据排序状态
onDragEnd = result => {
if (!result.destination) return;
const items = this.reorder(this.props.dataList, result.source.index, result.destination.index);
this.props.callBackOrder && this.props.callBackOrder(items);
};
展示一下使用方式与示例:
<Translation dataList={this.state.album_list_item} callBackOrder={this.callbackOrder}>
{this.state.album_list_item.map((item, index) => this.judgeBackElement(item.module_name, index, item))}
</Translation>
// 判断返回相应的组件
judgeBackElement = (type, index, data) => {
if (type == 'theme') return <AlbumThemeTemplate key={index} data={data} callBackType={this.callBackType} />;
if (type == 'album_list') return <AlbumListTemplate key={index} data={data} callBackType={this.callBackType} />;
};
Github react-beautiful-dnd网站:https://www.npmjs.com/package/react-beautiful-dnd