不能让React-Beautiful-DND和react -虚拟化一起工作



伙计们,我一直在努力让这个工作实际上几天,我还没能弄清楚。我可以让这两个库单独工作,但我被困在为什么它不会工作,当我把两者结合起来。我想我把它们联系错了,我就是不知道是怎么回事。请帮助。

尝试在这里遵循此指南。这里是指南的源代码。

这是我的问题的CodeSandBox。

最后是CodeSandBox中重要部分的代码片段:

getRowRender({ index, style }) {
const item = this.state.items[index];
return (
<Draggable draggableId={item.id} index={index} key={item.id}>
{(provided, snapshot) => (
<div
ref={provided.innerRef}
{...provided.draggableProps}
{...provided.dragHandleProps}
style={getItemStyle(
snapshot.isDragging,
provided.draggableProps.style
)}
>
{item.content}
</div>
)}
</Draggable>
);
}

render() {
if (this.state.items) {      
return (
<DragDropContext onDragEnd={this.onDragEnd}>
<Droppable
droppableId="droppable"
mode="virtual"
renderClone={(provided, snapshot, rubric) => (
<div
ref={provided.innerRef}
{...provided.draggableProps}
{...provided.dragHandleProps}
style={getItemStyle(
snapshot.isDragging,
provided.draggableProps.style
)}
>
{this.state.items[rubric.source.index].content}
</div>
)}
>
{(provided, snapshot) => (
<AutoSizer>
{({ height, width }) => (
<List
{...provided.droppableProps}
height={height}
rowCount={this.state.items.length}
rowHeight={500}
width={width}
ref={(ref) => {
// react-virtualized has no way to get the list's ref that I can so
// So we use the `ReactDOM.findDOMNode(ref)` escape hatch to get the ref
if (ref) {
// eslint-disable-next-line react/no-find-dom-node
const whatHasMyLifeComeTo = ReactDOM.findDOMNode(ref);
if (whatHasMyLifeComeTo instanceof HTMLElement) {
provided.innerRef(whatHasMyLifeComeTo);
}
}
}}
style={getListStyle(snapshot.isDraggingOver)}
rowRenderer={this.getRowRender}
/>
)}
</AutoSizer>
)}
</Droppable>
</DragDropContext>
);
} else {
return null;
}
}

我想我已经解决这个问题了。

https://codesandbox.io/s/vertical-list-forked-risye

你没有在你的rowRenderer中传递styles属性来以正确的方式虚拟化处理你的行

你的autosizing没有超过height: 0,因为它的父级没有任何样式。

如果有人还在寻找一个具有工作原型的活动沙盒。这是我回答并添加沙箱链接的帖子

react-beautiful-dnd与react-虚拟化表组件不能正常工作

下面是我将两个库结合使用的方法:

CodeSandbox演示
import ReactDOM from 'react-dom'
import { List } from 'react-virtualized'
import React, { memo, useState, useEffect } from 'react'
import { DragDropContext, Droppable, Draggable } from 'react-beautiful-dnd'
const padding = 10
const reorder = (list, startIndex, endIndex) => {
const result = Array.from(list)
const [removed] = result.splice(startIndex, 1)
result.splice(endIndex, 0, removed)
return result
}
const ListItem = memo(props => {
const {
item,
style,
index,
provided,
isDragging
} = props
return (
<div
data-index={index}
data-testid={item.id}
ref={provided.innerRef}
{...provided.draggableProps}
{...provided.dragHandleProps}
data-is-dragging={isDragging}
style={{
...style,
display: 'flex',
padding: '0 10px',
alignItems: 'center',
boxSizing: 'border-box',
marginBottom: `${padding}px`,
...provided.draggableProps.style,
backgroundColor: props.isDragging ? '#ccc' : '#eee'
}}
>
<div>{item.content}</div>
</div>
)
})
const rowRenderer = items => ({ index, style }) => {
const item = items[index]
if (!item) return null
const patchedStyle = {
...style,
top: style.top + padding,
left: style.left + padding,
height: style.height - padding,
width: `calc(${style.width} - ${padding * 2}px)`
}
return (
<Draggable
index={index}
key={item.id}
draggableId={item.id}
>
{(provided, snapshot) => (
<ListItem
item={item}
provided={provided}
style={patchedStyle}
isDragging={snapshot.isDragging}
/>
)}
</Draggable>
)
}
const Column = memo(({ items }) => {
return (
<div style={{ display: 'flex' }}>
<Droppable
mode='virtual'
droppableId='column'
renderClone={(provided, snapshot, rubric) => (
<ListItem
provided={provided}
isDragging={snapshot.isDragging}
item={items[rubric.source.index]}
/>
)}
>
{(droppableProvided, snapshot) => {
const itemCount = snapshot.isUsingPlaceholder
? items.length + 1
: items.length
return (
<List
width={300}
height={600}
rowHeight={50}
rowCount={itemCount}
ref={ref => {
if (ref) {
// eslint-disable-next-line react/no-find-dom-node
const whatHasMyLifeComeTo = ReactDOM.findDOMNode(ref)
if (whatHasMyLifeComeTo instanceof window.HTMLElement) {
droppableProvided.innerRef(whatHasMyLifeComeTo)
}
}
}}
style={{
transition: 'background-color 0.2s ease',
backgroundColor: snapshot.isDraggingOver ? '#0a84e3' : '#74b9ff'
}}
rowRenderer={rowRenderer(items)}
/>
)
}}
</Droppable>
</div>
)
})
export default () => {
const [items, setItems] = useState([])
useEffect(() => {
const generateItems = new Array(2500).fill().map((value, id) => (({
id: `id-${id}`,
content: `content ${id}`
})))
setItems(generateItems)
}, [])
const onDragEnd = result => {
if (!result.destination) return
setItems(reorder(
items,
result.source.index,
result.destination.index
))
}
return (
<DragDropContext onDragEnd={onDragEnd}>
<Column items={items} />
</DragDropContext>
)
}

最新更新