Добавить компоненты в фиксированный список с помощью окна реакции?
У меня есть фиксированный список и сетка с использованием окна реакции, бесконечного загрузчика и автосайзера. Он работает нормально, но я хочу добавить компонент до начала списка / сетки (например, поле поиска и кнопку). Какой правильный подход к этому? Я хочу, чтобы этот компонент прокручивался с фиксированным списком, а не отдельно. Я устал просто отрисовывать компонент раньше, но потом он не находится в контейнере фиксированного списка и не прокручивается вместе с ним.
{/* WANT TO ADD SOME SORT OF COMPONENT HERE SO IT CAN SCROLL WITH LIST */}
{/* CAN'T IN HERE BECAUSE ITS NOT INSIDE THE FIXED CONTAINER SO IT SCROllS SEPARATELY */}
<AutoSizer>
{({ height, width }) => (
<InfiniteLoader
isItemLoaded={index => index < stateData.data.length}
itemCount={stateData.data.length + 1}
loadMoreItems={loadMoreProducts}
>
{({ onItemsRendered, ref }) => (
<FixedSizeList
onItemsRendered={onItemsRendered}
ref={ref}
height={height}
itemCount={stateData.data.length + 1}
itemSize={350}
width={width}
>
{/* WANT TO ADD SOME SORT OF COMPONENT HERE SO IT CAN SCROLL WITH LIST */}
{/* CAN'T IN HERE BECAUSE ITS LOOPING LISTITEM */}
{ListItem}
</FixedSizeList>
)}
</InfiniteLoader>
)}
</AutoSizer>
Изменить: в значительной степени я не хочу, чтобы список (или сетка) и фактическая страница были двумя разными контейнерами прокрутки. Я бы хотел, чтобы вся страница прокручивалась вместе. Я столкнулся с этой проблемой, потому что некоторые из моих контейнеров должны иметь бесконечный список элементов, которые пользователи могут прокручивать, поэтому список необходимо виртуализировать для повышения производительности.
Смотрите демо здесь. На самом деле фиксированный контейнер следует рассматривать как всю страницу и поле поиска, а все остальное должно прокручиваться в бесконечном списке. Наличие двух разных контейнеров прокрутки не слишком хорошо для ux.
2 ответа
Если вы хотите, чтобы вся страница прокручивалась вместе с вашим виртуальным списком, вам понадобится скроллер окна. Это также включает в себя эксперименты со стилем. Чтобы окно поиска прокручивалось вместе со списком, вам понадобится фиксированная позиция. Разделитель div и некоторый стиль помогают иллюзии.
Я добавил сюда базовый скроллер окна и некоторые изменения стиля в вашем коде.
Несколько вариантов:
- Создайте оболочку вокруг автокорректора, которая будет содержать как ваше поле поиска, так и автоподатчик.
<>
<SearchBox />
<AutoSizer>
... your items
</AutoSizer>
</>
- пусть AutoSizer содержит и поиск, и список
<AutoSizer>
<SearchBox />
<List>
... your items
</List>
</AutoSizer>
- Поскольку ваша бесконечная прокрутка использует функцию рендеринга, вам могут понадобиться фрагменты
<AutoSizer>
<InfiniteScroll>
{({ onItemsRendered, ref }) => (
<>
<SearchBox />
<List>
... your items
</List>
<>
)}
</InfiniteScroll>
</AutoSizer>
Здесь я отредактировал ваш пример и заставил его работать, используя этот подход.
Обратите внимание, что страница прокручивается только из-за верхней и нижней полос; что является поведением в вашем примере.
- Позвольте бесконечному загрузчику заполнить массив и добавить к нему дополнительный элемент. Изделие может иметь определенный вид. Предполагая, что FixedSizeList - это компонент списка из
react-virtualized
тогда вы можете использовать его rowRenderer для визуализации элемента типа "поиск" иначе, чем другие элементы. Что-то типа:
function rowRenderer ({ key, type, value, ...rest }) {
if (type === 'search') {
return <Search key={key} placeholder={value} {...rest} />
}
return <div key={key} {...rest}>{value}</div>
}
// Render your list
ReactDOM.render(
<AutoSizer>
{({ height, width }) => (
<List
height={height}
rowCount={list.length}
rowHeight={20}
rowRenderer={rowRenderer}
width={width}
/>
)}
</AutoSizer>,
document.getElementById('example')
);
Возможно, также стоит взглянуть на простой пример от Вона.