首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用AutoSizer包装React-Beautiful+ React-Window虚拟列表时遇到的设置问题

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

Stack Overflow用户
提问于 2020-06-18 22:29:44
回答 1查看 2.5K关注 0票数 2

当我的虚拟列表<FixedSizeList>组件(react优美-dnd+react窗口)包装到一个<AutoSizer>组件(react-虚拟化-auto)时,我收到以下错误:

代码语言:javascript
复制
react-beautiful-dnd

A setup problem was encountered.

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

如果我不使用<FixedSizeList>组件包装<AutoResizer>并提供硬编码值,则不会发生错误。

我的程序实现了两个单独的,不拖放的列表,我可以来回拖放.因为列表不是可拖动的,它不是典型的“板”,但我使用React漂亮-DND的反应窗口基本板的CodeSandBox作为指南,使它同样工作。

List.js

代码语言:javascript
复制
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

代码语言:javascript
复制
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);

不管发生了什么错误,所有的事情似乎都在正常工作,但我真的很想在前进之前了解这个问题。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2020-06-19 18:09:14

我深入研究了AutoSizer组件以找到答案。

记录错误的原因是,由于childrenheight值是0,所以AutoSizer HOC的width属性没有呈现。这也是为什么所有东西仍然正常工作,因为widthheight状态值最终被更新,但只是在初始呈现之后。

AutoSizer (index.esm.js):

代码语言:javascript
复制
// 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)
);

因此,解决方案是为defaultWidthdefaultHeight 道具提供非零值,以确保组件在挂载上呈现,尽管使用的是非自动大小:

代码语言:javascript
复制
//...

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>
);
票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/62460388

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档