我是react.js
的新手,必须构建一个Table
并使用我正在使用react-beautiful-dnd
的行重新排序行为。我能够获得重新排序的行为,唯一的混乱是,特定行的所有列条目都显示在第一列中(下图)。
在这里,“ A”条目属于“第一”列,“ test *”属于“第二”列,但是它正在“第一”列中显示。以下是我编写的用于重新排序的代码。有人可以指出该错误以及如何解决该错误,或者我可以改进使其工作。
|
import React, {Component, type Node, Fragment} from 'react'
import PropTypes from 'prop-types'
import ReactDOM from 'react-dom'
import {DragDropContext, Droppable, Draggable} from 'react-beautiful-dnd'
import {Container, Label, Table} from 'reactstrap'
import type {
DraggableProvided,
DraggableStateSnapshot
} from 'react-beautiful-dnd'
import './components/style.css'
const reorder = (list, startIndex, endIndex) => {
const result = Array.from(list)
const [removed] = result.splice(startIndex, 1)
result.splice(endIndex, 0, removed)
return result
}
class TableDroppable extends React.Component {
render() {
return (
<Droppable droppableId='Table'>
{(provided, snapshot) => {
const bgColour = (snapshot.isDraggingOver) ?
'bg-primary' : 'bg-danger'
return (
<tbody
{...provided.droppableProps}
ref={provided.innerRef}
className={`list-group ${bgColour}`}
>
{this.props.renders.map((render, i) =>
<tr>
<RowDraggable
key={render.id}
id={render.id}
name={render.name}
index={i}
/>
</tr>
)}
{provided.placeholder}
</tbody>
)
}}
</Droppable>
)
}
}
TableDroppable.propTypes = {
renders: PropTypes.arrayOf(PropTypes.object),
}
const portal: HTMLElement = document.createElement('div')
portal.classList.add('dnd-portal')
if (!document.body) {
throw new Error('body not ready for portal creation')
}
document.body.appendChild(portal)
class PortalAwareItem extends Component<ItemProps> {
render() {
const provided: DraggableProvided = this.props.provided
const snapshot: DraggableStateSnapshot = this.props.snapshot
const usePortal: boolean = snapshot.isDragging
const bgColour = (snapshot.isDragging) ? 'secondary' : 'light'
const textColour = (snapshot.isDragging) ? 'text-light' : ''
const className = `list-group-item bg-${bgColour} ${textColour}`
const child: Node = (
<tr
{...provided.draggableProps}
{...provided.dragHandleProps}
ref={provided.innerRef}
className={className}
className={className}
inportal={usePortal.toString()}
>
<td>A</td>
<td>{this.props.name}</td>
</tr>
)
if (!usePortal) {
return child
}
return ReactDOM.createPortal(child, portal)
}
}
class RowDraggable extends React.Component {
render() {
return (
<Draggable draggableId={this.props.id} index={this.props.index}>
{(
draggableProvided: DraggableProvided,
draggableSnapshot: DraggableStateSnapshot
) => (
<PortalAwareItem
provided={draggableProvided}
snapshot={draggableSnapshot}
name={this.props.name}
/>
)}
</Draggable>
)
}
}
RowDraggable.propTypes = {
name: PropTypes.string.isRequired,
id: PropTypes.number.isRequired,
index: PropTypes.number.isRequired,
}
class TableDragAndDrop extends React.Component {
constructor(props) {
super(props)
this.state = {
renders: this.props.renders,
initialOrder: this.props.renders
}
this.onDragEnd = this.onDragEnd.bind(this)
}
onDragEnd(result) {
// Handle drop outside list.
if (!result.destination) {
return
}
const items = reorder(
this.state.renders,
result.source.index,
result.destination.index
)
this.setState({renders:items})
const newOrder = []
for (var i=0; i < items.length; i++) {
newOrder.push(items[i].id)
}
if (!!this.props.onDragEnd)
{ this.props.onDragEnd(newOrder) }
}
render() {
return (
<Container fluid className='text-left'>
<DragDropContext onDragEnd={this.onDragEnd}>
<Fragment>
<Table>
<thead>
<tr>
<th>First</th>
<th>Second</th>
</tr>
</thead>
<TableDroppable renders={this.state.renders} />
</Table>
</Fragment>
</DragDropContext>
</Container>
)
}
}
TableDragAndDrop.propTypes = {
renders: PropTypes.arrayOf(PropTypes.object).isRequired
}
export default TableDragAndDrop