1

官方文档示例中, itemSize 不支持内容:

const rowSizes = new Array(1000)
  .fill(true)
  .map(() => 25 + Math.round(Math.random() * 50));

const getItemSize = index => rowSizes[index];

我试图弄清楚如何使用下面的代码(它基于官方react-window-infinite-loader示例,尽管我已经将它重构为基于钩子)。

下面的代码有VariableSizeList,AutoSizerInfiniteLoader显示来自 API 的数据。

import React, { useState } from "react";
import { VariableSizeList as List } from "react-window";
import InfiniteLoader from "react-window-infinite-loader";
import AutoSizer from "react-virtualized-auto-sizer";
import axios from "axios";
import { LoremIpsum } from "react-lorem-ipsum";

export default function ExampleWrapper() {
  const [hasNextPage, setHasNextPage] = useState(true);
  const [isNextPageLoading, setIsNextPageLoading] = useState(false);
  const [items, setItems] = useState([]);

  const _loadNextPage = (...args) => {
    setIsNextPageLoading(true);
    setHasNextPage(items.length < 100);

    axios
      .get(
        `https://randomuser.me/api/?results=5&page=1&inc=name,gender,email,nat&noinfo`
      )
      .then((response) => {
        // console.log("response", response.data.results);
        setItems([...items, ...response.data.results]);
        // console.log("items", items);
        setIsNextPageLoading(false);
      })
      .catch((error) => {
        setIsNextPageLoading(false);
        console.error("Error:", error);
      });
    setIsNextPageLoading(false);
  };

  // If there are more items to be loaded then add an extra row to hold a loading indicator.
  const itemCount = hasNextPage ? items.length + 1 : items.length;

  // Only load 1 page of items at a time.
  // Pass an empty callback to InfiniteLoader in case it asks us to load more than once.
  const loadMoreItems = isNextPageLoading ? () => {} : _loadNextPage;

  // Every row is loaded except for our loading indicator row.
  const isItemLoaded = (index) => !hasNextPage || index < items.length;

  // Render an item or a loading indicator.
  const Item = ({ index, style }) => {
    // console.log(items[index].email);
    const content = !isItemLoaded(index) ? (
      "Loading..."
    ) : (
      <div style={{ display: "flex" }}>
        <div>{index}</div>
        <div>{items[index].email}</div>
        <div>
          <LoremIpsum random={true} />
        </div>
      </div>
    );

    return (
      <div key={index} style={style}>
        {content}
      </div>
    );
  };

  return (
    <div style={{ height: "100vh" }}>
      <AutoSizer>
        {({ height, width }) => (
          <InfiniteLoader
            isItemLoaded={isItemLoaded}
            itemCount={itemCount}
            loadMoreItems={loadMoreItems}
          >
            {({ onItemsRendered, ref }) => (
              <List
                className="List"
                height={height}
                itemCount={itemCount}
                itemSize={() => 100}
                onItemsRendered={onItemsRendered}
                ref={ref}
                width={width}
              >
                {Item}
              </List>
            )}
          </InfiniteLoader>
        )}
      </AutoSizer>
    </div>
  );
}

这是工作代码框链接中的上述代码。

如何让行不重叠?

我发现了一个似乎导致重叠行的代码示例:https ://codesandbox.io/s/yw4ok6l69z

还有另一个看起来很复杂的例子,我不知道它是如何工作的,也不知道如何让它适应上面的例子:https ://codesandbox.io/s/bugreact-window-dynamic-size-list-djegq 。好像这个例子使用DynamicSizeList的是尚未正式发布的?

4

0 回答 0