reactjs 无法让React-Beautiful-DND和React-Virtualized一起工作

68de4m5k  于 2023-04-20  发布在  React
关注(0)|答案(3)|浏览(184)

伙计们,我已经试着让这个工作了几天,我还没有能够弄清楚这个问题。我可以让两个库单独工作,但我被困在为什么当我把两者结合起来时它不会工作。我想我把它们连接错了,我只是不知道它是什么。请帮助。
尝试遵循此指南here。指南here的源代码。
Here is a CodeSandBox of my issue
最后,这里是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;
    }
  }
nwnhqdif

nwnhqdif1#

我想我解决了这个问题。
https://codesandbox.io/s/vertical-list-forked-risye
您没有在rowRenderer中传递styles属性来虚拟化以正确的方式处理行。
此外,您的自动测瓣器未超过身高:0,因为它的父项没有任何样式。

3xiyfsfu

3xiyfsfu2#

如果任何人仍然在寻找一个工作原型的活动沙箱。这里是我回答并添加沙箱链接的帖子
react-beautiful-dnd doesn’t work properly with react-virtualized Table component

mftmpeh8

mftmpeh83#

下面是我一起使用这两个库的方法。
CodeSandbox demo

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>
  )
}

相关问题