React封装 列表拖拽排序高阶组件

引言

项目开发中,特别是后台数据管理端,经常需要用到数据列表拖拽排序的需求,又不需要改变原有的数据结构与布局的情况下,使用高阶组件无疑是最好的选择,接下来于小伙伴们分享一下个人经验:

首先咱们给予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

猜你喜欢

转载自blog.csdn.net/smile_ycm/article/details/87723903