【一文一问】2种方式实现React动态渲染长列表

561 阅读1分钟

背景

假设后端提供了一万条数据,难道直接简单粗暴地一股脑渲染到页面上?有没有更优雅的方法?

有啊,而且是两个:rc-virtual-list、react-window。这两个库专用于动态渲染长列表,只会渲染可视区域,很大程度上提升了页面性能。两个库的作者为同一人,rc-virtual-list是其早期作品,react-window是前者的重写,更轻量、快速。

1,rc-virtual-list

用法:

import List from 'rc-virtual-list';

<List data={[0, 1, 2]} height={200} itemHeight={30} itemKey="id">
  {index => <div>{index}</div>}
</List>;

api:

image.png 例子:

// 造数据user数组,内有10000条数据,每条数据是个包含name、age、birthday、city、id的对象
import Mock from 'mockjs'

export default Mock.mock('https://test.com','get',()=>{
  let data = Mock.mock({
    'user|10000':[{
      'name': '@cname',
      'age|0-70' : 0,
      'birthday' :'@date("yyyy-MM-dd")',
      'city' : '@city(true)',
      'id|+1':0
    }]
  })
  return data
})
 // App.js
 <List data={user} height={675} itemHeight={20} itemKey='id'>
 // data为数据源,height为列表总高度,itemHeight为子项高度,itemKey为子项key
          {(item,index,props) =>{
           let {name,city} = item // 遍历数组,item为数组内的对象
           return <div>{index+1}, {name} 来自 {city}</div>
           }
          }
</List>

效果:

image.png

2,react-window

用法:

import {FixedSizeList} from 'react-window'

render(){
    const {user} = this.state
    const offerListItemFunc = ({data,index,style})=>{
      console.log('data,index,style', data,index,style) 
      //注意data为user数组,不是数组里的每个子项,index为数组item索引,style为添加给子项的样式。user还是上述用Mock造的数据
        return <div key={index} style={style}>{index+1}, {data[index].name} 来自 {data[index].city}</div>
    }
    return (
      <>
       <FixedSizeList
        height={675} //列表高度
        width={500} //列表宽度
        itemCount={10000} //子项总数
        itemSize={20} //子项高度
        itemData={user} //数据源
       >
       {offerListItemFunc} //函数,渲染一个组件
        {/* {({data,index,style})=>{
        console.log('data,index,style', data,index,style)
        return <div key={index} style={style}>{index+1}, {data[index].name} 来自 {data[index].city}</div>
        }} */} //也可直接定义函数,一样的
       </FixedSizeList>
      </>
    )
  }

效果:

image.png