Is there any way to implement virtualization to react-sortablejs

144 Views Asked by At

I am trying to implement virtualization with react-sortablejs for lists with more than 500 items.

I have tried with react-virtuoso, but react-sortablejs wraps the entire react-virtuoso component as a single item. Is there any way to target the li element inside of react-virtuoso itemContent?

<ReactSortable
 tag="ul"
 ...sortableOptions
>
  <Virtuoso
    totalCount={500}
    itemContent={(index)=> <li>Item {index} </li>}
  />
</ReactSortable>
1

There are 1 best solutions below

0
On

It probably won't work because it requires setList and updates the list while moving mouse.

Here is an alternative: https://virtuoso.dev/react-sortable-hoc/

import { useState, forwardRef } from 'react'
import { Virtuoso } from 'react-virtuoso'
import { sortableElement, sortableContainer } from "react-sortable-hoc"

const SortableContainer = sortableContainer(({ listRef, ...props }) => <ul {...props} ref={listRef} />)
const SortableItem = sortableElement((props) => <li {...props} />)

function App() {
  const [state, setState] = useState([...Array(100)].map((_, i) => +i))

  const components = {
    List: forwardRef((props, ref) => {
      return <SortableContainer {...props} listRef={ref} onSortEnd={({ newIndex, oldIndex }) => {
        if (newIndex !== oldIndex) {
          const temp = state[newIndex]
          state[newIndex] = state[oldIndex]
          state[oldIndex] = temp
          setState([...state])
        }
      }} />
    }),
    Item: (props) => {
      const { ['data-index']: index } = props
      return <SortableItem index={index} {...props} />
    },
  }

  return (
    <Virtuoso
      style={{ width: 110, height: 500 }}
      data={state}
      components={components}
      itemContent={(index, row) => <>Item {row}</>}
    />
  )
}

export default App