Проблема с установкой, возникшая при обертке виртуального списка React-Beautiful-DND + React-Window с помощью AutoSizer - PullRequest
0 голосов
/ 19 июня 2020

При упаковке моего виртуального списка <FixedSizeList> компонент ( react-beautiful-dnd + response-window ) с компонентом <AutoSizer> ( react-virtualized-auto -sizer ) Я получаю следующую ошибку:

react-beautiful-dnd

A setup problem was encountered.

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

Ошибка не возникает, если я не оберну компонент <FixedSizeList> с помощью <AutoResizer> и не предоставлю жестко заданные значения вместо.

Моя программа реализует 2 отдельных, не перетаскиваемых списка, в которые я могу перетаскивать и из них. Поскольку списки нельзя перетаскивать, это не типичная «доска», но я использовал React-Beautiful-DND's CodeSandBox для React-Window Basi c Board в качестве руководства по созданию он работает так же хорошо.

Список. 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:

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);

Независимо от ошибки, кажется, что все работает должным образом, но мне бы очень хотелось разобраться в проблеме, прежде чем двигаться дальше.

1 Ответ

0 голосов
/ 19 июня 2020

Я углубился в компонент AutoSizer , чтобы найти ответ.

Ошибка была зарегистрирована, потому что свойство children AutoSizer HO C было не обрабатывается, поскольку значения width и height были 0. По этой же причине все по-прежнему функционировало нормально, поскольку значения состояния width и height были в конечном итоге обновлены, но только после первоначального рендеринга.

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)
);

Следовательно, решение состоит в том, чтобы предоставить defaultWidth и defaultHeight реквизиты с ненулевым значением, чтобы гарантировать, что компонент рендеринг на монтировке, правда, с неавтоматизированными размерами:

//...

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>
);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...