我想将react-sortable-hoc与react-virtualized 的 MultiGrid一起使用。更具体地说,我希望能够对右下方网格中的行进行排序。
第一次尝试
我正在使用创建一个 SortableMultiGrid
const SortableMultiGrid = SortableContainer(MultiGrid, {
withRef: true,
});
但是当这个安装我得到一个错误,这个消息
无法读取未定义的属性“ownerDocument”
该错误源自SortableContainer
的 componentDidMount 方法。
第二次尝试
我发现它SortableContainer
有一个getContainer
属性,它在引发错误的代码上方被调用:
返回可滚动容器元素的可选函数。此属性默认为 SortableContainer 元素本身或(如果 useWindowAsScrollContainer 为 true)窗口。使用此函数来指定自定义容器对象(例如,这对于与某些 3rd 方组件(例如 FlexTable)集成很有用)。这个函数被传递了一个参数(wrappedInstance React 元素),它应该返回一个 DOM 元素。
它是用 MultiGrid 组件实例调用的,但是当我尝试从中获取 DOM 节点时,它返回null
:
getContainer={e => {
const multiGrid = ReactDOM.findDOMNode(e);
// multiGrid is null - I must return an HTMLElement
}}
我怀疑这可能是由尚未安装的 MultiGrid 组件引起的,我怀疑我所看到的与https://github.com/clauderic/react-sortable-hoc/issues/135有关。
第三次尝试 - 有效,但这是一个黑客
我想我可能会通过首先返回不会引发错误的东西来欺骗 SortableContainer,然后当可以确定对多网格内右下角网格的引用时,我可以再次调用 SortableContainer 的 componentDidMount。
<SortableMultiGrid
// ...
ref={sortableGrid => {
if (sortableGrid) {
const multiGrid = sortableGrid.getWrappedInstance();
if (multiGrid && multiGrid._bottomRightGrid) {
const bottomRightGrid = multiGrid._bottomRightGrid;
const bottomRightGridNode = ReactDOM.findDOMNode(
bottomRightGrid
);
this.bottomRightGrid = bottomRightGridNode;
// HACK: We shouldn't ever call componentDidMount on components
sortableGrid.componentDidMount();
}
}
}}
getContainer={e => {
if (this.bottomRightGrid) {
return this.bottomRightGrid;
} else {
// If its unknown - return something that wont throw errors
return {
ownerDocument: document,
addEventListener: () => { },
removeEventListener: () => { }
};
}
}}
/>
这实际上似乎有效!但是我仍然想知道是否有人对如何以更优雅的方式实现这一点或两个库中的任何一个应该如何更改以解决此问题有想法。
代码沙盒
我制作了两个沙箱来说明这一点:
- 第一个是功能性可排序网格(我没有实现要持久化的最终状态):https ://codesandbox.io/s/710kxo247x 。我实现了一个渲染单元格行的“rowRangeRenderer”(注意它在滚动时没有完全优化缓存),以替换 defaultCellRangeRenderer 并允许由 SortableElement HOC 包装行。
- 尝试使用 MultiGrid 而不是 Grid - 显示上述错误:https ://codesandbox.io/s/1z390ow44
- 第三次尝试 - 它有点工作,但它是一个黑客https://codesandbox.io/s/pprwo6m350