React-virtualized - 是不是可以在窗口调整大小时更新 rowHeights?

Posted

技术标签:

【中文标题】React-virtualized - 是不是可以在窗口调整大小时更新 rowHeights?【英文标题】:React-virtualized - Is it possible to update rowHeights on window resize?React-virtualized - 是否可以在窗口调整大小时更新 rowHeights? 【发布时间】:2021-10-15 08:38:53 【问题描述】:

我正在使用 React-virtualized 为我正在制作的社交媒体网络应用程序呈现大量无限的帖子列表。 CellMeasurer 用于允许动态 rowHeights,如果窗口保持相同大小,它就可以工作。

我尝试关注docs,但如果调整浏览器窗口大小,我无法让它重新计算 rowHeights。这就是问题的样子,下面是代码: overlapping rows image

function InfiniteList(
  getDataFromServer,
  children,
  infiniteLoaderRef,
  list,
  updateList,
  empty,
  id,
) 
  const [isNextPageLoading, setIsNextPageLoading] = useState(false);
  let listRef = useRef(null);
  let hasNextPage = true;

  const cache = new CellMeasurerCache(
    defaultHeight: 200,
    fixedWidth: true,
  );

  useEffect(() => 
    window.addEventListener("resize", () => updateRowHeight());

    return () => window.removeEventListener("resize", updateRowHeight);
  , []);

  function updateRowHeight() 
    if (!listRef) 
      return;
    
    console.log("recompute");
    cache.clearAll();
    listRef.current.recomputeRowHeights();
  

  // 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 loadMoreRows = isNextPageLoading ? () =>  : loadNextPage;

  // // Every row is loaded except for our loading indicator row.
  const isRowLoaded = ( index ) => 
    if (!list) 
      return false;
     else 
      return !hasNextPage || index < list.length;
    
  ;

  async function loadNextPage( startIndex, stopIndex ) 
    setIsNextPageLoading(true);
    const rows = await getDataFromServer(startIndex, stopIndex);
    if (!list) 
      updateList(rows);
     else 
      const newList = list.concat(rows);
      cache.clearAll();
      updateList(newList);
    
    setIsNextPageLoading(false);
  

  const rowCount = () => (!list ? 1 : list.length);

  function rowRenderer( key, index, style, parent ) 
    if (!list) 
      return <TwitSpinner key=key style=style size=50 />;
     else 
      return (
        <CellMeasurer
          cache=cache
          columnIndex=0
          key=key
          parent=parent
          rowIndex=index
        >
          <div style=style>
            React.cloneElement(children, 
              listItem: list[index],
            )
          </div>
        </CellMeasurer>
      );
    
  

  function noRowsRenderer() 
    return <React.Fragment>empty</React.Fragment>;
  

  return (
    <InfiniteLoader
      key=id
      isRowLoaded=isRowLoaded
      loadMoreRows=loadMoreRows
      rowCount=10000
      minimumBatchSize=50
      ref=infiniteLoaderRef
    >
      ( onRowsRendered, registerChild ) => (
        <WindowScroller>
          ( height, isScrolling, onChildScroll, scrollTop ) => (
            <AutoSizer disableHeight>
              ( width ) => (
                <List
                  autoHeight
                  height=height
                  isScrolling=isScrolling
                  onScroll=onChildScroll
                  deferredMeasurementCache=cache
                  onRowsRendered=onRowsRendered
                  ref=(reference) => 
                    registerChild(reference);
                    listRef.current = reference;
                  
                  rowCount=rowCount()
                  rowHeight=cache.rowHeight
                  rowRenderer=rowRenderer
                  scrollTop=scrollTop
                  width=width
                  overscanRowCount=5
                  noRowsRenderer=noRowsRenderer
                />
              )
            </AutoSizer>
          )
        </WindowScroller>
      )
    </InfiniteLoader>
  );


export default InfiniteList;

【问题讨论】:

【参考方案1】:

现在我从 loadNextPage 函数中删除了 cache.clearAll() 。

async function loadNextPage( startIndex, stopIndex ) 
    setIsNextPageLoading(true);
    const rows = await getDataFromServer(startIndex, stopIndex);
    if (!list) 
      updateList(rows);
     else 
      const newList = list.concat(rows);
      cache.clearAll(); //removed
      updateList(newList);
    
    setIsNextPageLoading(false);
  

【讨论】:

以上是关于React-virtualized - 是不是可以在窗口调整大小时更新 rowHeights?的主要内容,如果未能解决你的问题,请参考以下文章

如何滚动到通过 react-virtualized 呈现的 React 元素?

react 分页器 基于react-virtualized组件的分页器

React-virtualized 中对 registerChild 的 CellMeasurer 支持

无法让 React-Beautiful-DND 和 React-Virtualized 一起工作

React-virtualized 动态高度列表呈现最初堆叠的所有内容

react-virtualized WindowScroller 性能问题