I'm using react-dnd to support drag and drop operations on rows of lists rendered by a FixedSizeList. The react-window package has been great at managing long lists and improving overall performance, however there is an issue that I haven't been able to resolve.
Essentially, react-window causes the refs of rows to be invalidated each time a re-render occurs.
As an example. say a user starts dragging a row. react-dnd sees this, updates its internal state accordingly and the row receives a prop notifying it that it is being dragged. However, if the list re-renders as a result of state mutation, the refs for each row are invalidated and recreated. And if a dragging operation is taking place while a re-render occurs, this causes react-dnd to reset its state. The user-visible side-effect of this is that the row being dragged loses knowledge of this.
I've attached a small demonstrator project created with "create-react-app" that reproduces this issue. Running yarn install && yarn start, you will be presented with a page containing two lists. The top one is rendered without react-window, the bottom one uses FixedSizeList. Dragging an element from the top list should cause the affected row's checkbox to toggle, however the same behavior isn't seen in the bottom list managed by react-window. Opening the devconsole should reveal the cause for this: the refs are being recreated as a result of the multiple renders that take place whenever a row's parent state mutates.
Looks like the same thing as #308
You're using an inline item renderer. Because this renderer's "type" (the function definition) gets recreated each time the parent component renders, React deeply unmounts and remounts the entire rendered subtree.
This is why all of the docs examples avoid showing inline functions and it's why the itemData API exists: https://react-window.now.sh/#/examples/list/memoized-list-items
This is something I plan to change in version 2 (see #302)
Most helpful comment
Looks like the same thing as #308
You're using an inline item renderer. Because this renderer's "type" (the function definition) gets recreated each time the parent component renders, React deeply unmounts and remounts the entire rendered subtree.
This is why all of the docs examples avoid showing inline functions and it's why the
itemDataAPI exists: https://react-window.now.sh/#/examples/list/memoized-list-itemsThis is something I plan to change in version 2 (see #302)