简体   繁体   English

使用 AutoSizer 包装 React-Beautiful-DND + React-Window 虚拟列表时遇到的设置问题

[英]Setup problem encountered by wrapping a React-Beautiful-DND + React-Window virtual list with AutoSizer

When wrapping my virtual list <FixedSizeList> component ( react-beautiful-dnd + react-window ) with an <AutoSizer> component ( react-virtualized-auto-sizer ) I'm receiving the following error:当用<AutoSizer>组件( react-virtualized-auto-sizer )包装我的虚拟列表<FixedSizeList>组件( react-beautiful-dnd + react-window )时,我收到以下错误:

react-beautiful-dnd

A setup problem was encountered.

Invariant failed: provided.innerRef has not been provided with a HTMLElement.

The error doesn't occur if I don't wrap the <FixedSizeList> component with <AutoResizer> and supply hard-coded values instead.如果我不使用<AutoResizer>包装<FixedSizeList>组件并提供硬编码值,则不会发生错误。

My program implements 2 separate, non-draggable lists that I can drag-and-drop to and from.我的程序实现了 2 个独立的、不可拖动的列表,我可以从中拖放它们。 Becasue the lists aren't draggable it's not a typical "board", but I used React-Beautiful-DND's CodeSandBox for React-Window Basic Board as a guide to make it work just as well.因为列表不可拖动,所以它不是典型的“板”,但我使用React-Beautiful-DND 的 CodeSandBox for React-Window Basic Board作为指南,使其也能正常工作。

List.js :列表.js

import { Draggable, Droppable } from "react-beautiful-dnd";
import { FixedSizeList } from "react-window";
import AutoSizer from "react-virtualized-auto-sizer";
import ListItem from "./ListItem";
import React, { memo, useCallback } from "react";

const List = ({

        ID,
        data
    }) => {

    const listItemRenderer = useCallback(({ data, index, style }) => {

        const item = (data && data[index]);

        if (!item) {

            return null;
        }

        return (

            <Draggable
                key={item.ID}
                draggableId={item.ID}
                index={index}
            >
                {(provided) =>

                    <ListItem
                        data={item}
                        draggableProvided={provided}
                        virtualStyle={style}
                    />
                }
            </Draggable>
        );
    }, []);

    return (

        <Droppable
            droppableId={ID}
            mode={"virtual"}
            renderClone={(provided, snapshot, rubric) => (

                <ListItem
                    data={data[rubric.source.index]}
                    draggableProvided={provided}
                    isDragging={snapshot.isDragging}
                />
            )}
        >
            {(provided, snapshot) => {

                const dataLength = (data)
                    ? data.length
                    : 0;

                const itemCount = (snapshot.isUsingPlaceholder)
                    ? dataLength + 1
                    : dataLength;

                return (

                    <AutoSizer>  //Error here caused by wrapping <FixedSizeList> with <AutoSizer>
                        {({ width, height }) => (

                            <FixedSizeList
                                width={width}   //AutoSizer supplied value
                                height={height} //AutoSizer supplied value
                                itemSize={100}
                                itemCount={itemCount}
                                itemData={data}
                                outerRef={provided.innerRef}
                            >
                                {listItemRenderer}
                            </FixedSizeList>
                        )}
                    </AutoSizer>
                );
            }}
        </Droppable>
    );
};

export default memo(List);

ListItem.js : ListItem.js

import React, { memo } from "react";

const ListItem = ({

        data,
        draggableProvided,
        virtualStyle
    }) => {

    return (

        <div
            {...draggableProvided.draggableProps}
            {...draggableProvided.dragHandleProps}
            ref={draggableProvided.innerRef}
            style={{

                ...draggableProvided.draggableProps.style,
                ...virtualStyle
            }}

        >
            {data.name}
        </div>
    );
};

export default memo(ListItem);

Regardless of the error, everything seems to still function as it should, but I'd really like to understand the problem before moving forward.不管错误如何,一切似乎仍然是 function,但我真的很想在继续之前了解问题。

I dug into theAutoSizer component to find the answer.我深入研究了AutoSizer组件以找到答案。

The error was logged because the children property of the AutoSizer HOC was not being rendered since the width and height values were 0 .记录错误是因为 AutoSizer HOC 的children属性没有被渲染,因为widthheight值为0 This is also why everything still functioned normally, as the width and height state values were eventually updated, but only after the initial render.这也是为什么一切仍然正常运行的原因,因为最终更新了widthheight state 值,但只是在初始渲染之后。

AutoSizer (index.esm.js): AutoSizer (index.esm.js):

// Avoid rendering children before the initial measurements have been collected.
// At best this would just be wasting cycles.
var bailoutOnChildren = false;

if (!disableHeight) {
if (height === 0) {
    bailoutOnChildren = true;
}
outerStyle.height = 0;
childParams.height = height;
}

if (!disableWidth) {
if (width === 0) {
    bailoutOnChildren = true;
}
outerStyle.width = 0;
childParams.width = width;
}

return createElement(
'div',
{
    className: className,
    ref: this._setRef,
    style: _extends({}, outerStyle, style) },
!bailoutOnChildren && children(childParams)
);

Therefore, the solution is to supply defaultWidth and defaultHeight props with non-zero value to ensure that the component renders on mount, albeit with non-automated sizes:因此,解决方案是提供具有非零值的defaultWidthdefaultHeight 道具,以确保组件在安装时呈现,尽管具有非自动大小:

//...

return (

    <AutoSizer
        defaultWidth={1}
        defaultHeight={1}
    >
        {({ width, height }) => (

            <FixedSizeList
                width={width} 
                height={height}e
                itemSize={100}
                itemCount={itemCount}
                itemData={data}
                outerRef={provided.innerRef}
            >
                {listItemRenderer}
            </FixedSizeList>
        )}
    </AutoSizer>
);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM