惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

AI
AI
O
OpenAI News
Engineering at Meta
Engineering at Meta
F
Fortinet All Blogs
Jina AI
Jina AI
D
Docker
N
News and Events Feed by Topic
TaoSecurity Blog
TaoSecurity Blog
雷峰网
雷峰网
V
V2EX
小众软件
小众软件
N
News | PayPal Newsroom
GbyAI
GbyAI
Recorded Future
Recorded Future
SecWiki News
SecWiki News
WordPress大学
WordPress大学
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
酷 壳 – CoolShell
酷 壳 – CoolShell
Security Latest
Security Latest
Google DeepMind News
Google DeepMind News
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
Hacker News: Ask HN
Hacker News: Ask HN
Project Zero
Project Zero
Cyberwarzone
Cyberwarzone
MyScale Blog
MyScale Blog
T
The Blog of Author Tim Ferriss
U
Unit 42
The Last Watchdog
The Last Watchdog
V
Visual Studio Blog
C
Cisco Blogs
T
Tor Project blog
Google Online Security Blog
Google Online Security Blog
I
InfoQ
Attack and Defense Labs
Attack and Defense Labs
Y
Y Combinator Blog
博客园 - 聂微东
L
LangChain Blog
Blog — PlanetScale
Blog — PlanetScale
Apple Machine Learning Research
Apple Machine Learning Research
S
Schneier on Security
S
Securelist
博客园_首页
W
WeLiveSecurity
P
Privacy International News Feed
S
SegmentFault 最新的问题
博客园 - 【当耐特】
L
LINUX DO - 热门话题
Latest news
Latest news
大猫的无限游戏
大猫的无限游戏
M
MIT News - Artificial intelligence

webfem

react-virtualized AutoSizer 实现原理详解 - webfem JWT技术详解:从入门到精通 - webfem 如何在电脑上调试手机网页 - webfem MongoDB 入门详解 - webfem react-virtualized 无限列表图片闪屏问题修复 - webfem 博客搭建-创建文章接口 - webfem 代码相似性检查机制 - webfem WebSocket 技术详解:实时通信的利器 - webfem 小米YU7购车记-新能源购置税计算器的诞生 - webfem 手动搭建个人博客 - webfem 博客搭建-项目工程搭建 - webfem Base64编码详解:原理、应用与实践 - webfem 字数统计算法深度解析:从Unicode到实际应用的硬核技术实现 - webfem 衬线体与无衬线体:字体设计的经典对决 - webfem 如何把 小程序 转换为 VUE - webfem 性能优化-核心指标-FP - webfem MD5算法原理及其实现 - webfem 性能优化-核心指标-SI 的介绍与优化 - webfem 如何设计一个后端管理平台 - webfem
react-virtualized 的用法详解 - webfem
yimin,2316114920@qq.com · 2025-12-22 · via webfem

简介

在开发向下滑动列表模块时,我们一般会在元素滚动到底部时,加载新的数据,往后增加dom。然后循环这个过程。一旦数据量很大,因为页面渲染了很多的 dom,这个页面就会很卡顿。接下来就是老板让优化渲染性能。。。

聪明的你马上想到,我们能看到的数据只有外层div这么高一个高度,但是却渲染了海量的数据,那么可以只渲染可视区域的数据,不可见的直接删除掉不就行了。

但是,马上问题就来了,如果要这么实现,怎么保证删除元素之后,当前元素的位置不变,在什么位置删,会不会删多了导致滑动过程中页面展示白屏等等一系列问题。想想都有些头大,这时,react-virtualized 就是其中一个很好的解决方案。

npm 展示

react-virtualized 的 dom 结构

dom 结构

如图所示,react-virtualized 在实现无线滚动时,做了如下操作

  1. 创建一个相对定位 (relative)的盒子

  2. 列表元素设计为绝对定位(absolute),它的 top 位置相对于盒子顶部,这样,元素位置不会因为其他兄弟节点而变化

  3. 滚动过程总,根据可是区域的变化,删除或者增加节点

整个过程就是这样,只是内部的计算,位置处理比较繁琐。下面我们讲一下其组件的一些用法

核心组件

AutoSizer

先看用法

import AutoSizer from 'react-virtualized/dist/es/AutoSizer';

<AutoSizer>
     {({ height, width }) => {
       return <div style={{height, width}} />
     }
</AutoSizer>

AutoSizer 组件很简单,核心就是获取可视壳子的宽高,如果把这个组件包裹在外层,它能给内部提供一个真的宽高,方便内部组件调用。

对一些不确定宽高的组件比较适用,如果可视窗口比较稳定,也可以不用。

点击可以看更详细的实现原理>>

InfiniteLoader

通过名字可以大概知道意思,无限加载,这个组件给我们提供一个滚到到底部触发加载的时机,这样,我们不用计算,考虑什么时候元素滚动到最底部,要请求接口的时机。

示例如下

<InfiniteLoader
    isRowLoaded={({index}) => boolean}
    loadMoreRows={() = >{...}}
    rowCount={15}
    threshold={3}
>
       ...
</InfiniteLoader>

这个组件有四个核心属性

属性 类型 说明
isRowLoaded Function 计算当前行是否已经加载了
loadMoreRows Function 加载更多数据的函数
rowCount Number 一共的数据行数
threshold Number 提前多少行,开始请求数据,默认15行

List

List 则是提供一个列表的渲染组件

先看用法

import React from 'react';
import ReactDOM from 'react-dom';
import {List} from 'react-virtualized';

// List data as an array of strings
const list = [
  'Brian Vaughn',
  // And so on...
];

function rowRenderer({
  key, // Unique key within array of rows
  index, // Index of row within collection
  isScrolling, // The List is currently being scrolled
  isVisible, // This row is visible within the List (eg it is not an overscanned row)
  style, // Style object to be applied to row (to position it)
}) {
  return (
    <div key={key} style={style}>
      {list[index]}
    </div>
  );
}

// Render your list
ReactDOM.render(
  <List
    width={300}
    height={300}
    rowCount={list.length}
    rowHeight={20}
    rowRenderer={rowRenderer}
  />,
  document.getElementById('example'),
);

List 几个必传的属性如下

属性 类型 说明
width Number 可是区域的宽
height Number 可是区域的高度
RowCount Number Function 总行数,可以是固定值,也可以通过函数计算得到,返回一个数字
Rowheight Number Function 每一行的高度,可以是固定值,也可以通过函数计算得到,返回一个数字
rowRenderer Function 每一行的渲染函数

其中 RowCount 和 Rowheight 可以设置为固定值,亦可以用函数动态计算

rowRenderer 则是一个渲染函数,需要注意两点

  1. key 设置为 index

  2. 必须传入 style,这个 style 是动态计算出来的,为设定好元素的height 和 top值,不设置 style,则元素的位置不对。

<div key={key} style={style}>
      {list[index]}
 </div>

这里,key 和 style 必传

总结

我们来总结一下,实现一个无限滚动需要的内容

总结

通过三个组件的配置,最终实现整个无限滚动需求。看起来整个过程还是比较繁琐的,需要理解一些原理,以及很多组件的使用方法。

但是,如果把所有内容放在一起,对与开发者的心理成本可能又会上一个台阶,通过这样分部拆解,希望可以好理解一点。

最后,我们在写一个完整的例子

import AutoSizer from 'react-virtualized/dist/es/AutoSizer';
import List from 'react-virtualized/dist/es/List';
import InfiniteLoader from 'react-virtualized/dist/es/InfiniteLoader';

function Demo() {
  const [list, setList] = useState([])

// 加载下一组数据的函数
const loadMoreRows = () => {
  setTimeout(() => {
    setList([...list, ..[2, 4, 5]])
  }, 200)
}

// 加载组件,元素是否加载
const isRowLoaded = ({index}) => {
  return index < list.length
}

// 渲染 lists 的但组件渲染函数
const rowRenderer = ({index, style}) => {
  return (
    <div key={key} style={style}>
      {list[index]}
    </div>
  )
}


return (
  <AutoSizer>
   {({ height, width }) => {
     return return (
        <InfiniteLoader
          isRowLoaded={isRowLoaded}
          loadMoreRows={loadMoreRows}
          rowCount={list.length}
          threshold={2}
        >
          <List
              width={width}
              height={height}
              rowCount={list.length}
              rowHeight={20}
              rowRenderer={rowRenderer}
            />
        </InfiniteLoader>
   }
</AutoSizer>
)
}

原文地址:https://webfem.com/post/react-virtualized,转载请注明出处