react动态创建菜单并实现局部刷新(使用react-virtualized实现图片动态高度长列表的问题)
类别:编程学习 浏览量:2606
时间:2022-03-29 03:45:06 react动态创建菜单并实现局部刷新
使用react-virtualized实现图片动态高度长列表的问题目录
- 开发中遇到的问题
- 解决方案
- 具体实现
- 实际效果
- 小结
虚拟列表是一种根据滚动容器元素的可视区域来渲染长列表数据中某一个部分数据的技术。虚拟列表是对长列表场景一种常见的优化,毕竟很少有人在列表中渲染上百个子元素,只需要在滚动条横向或纵向滚动时将可视区域内的元素渲染出即可。
开发中遇到的问题1.长列表中的图片要保持原图片相同的比例,那纵向滚动在宽度不变的情况下,每张图片的高度就是动态的,当该列表项高度发生了变化,会影响该列表项及其之后所有列表项的位置信息。
2.图片width,height必须在图片加载完成后才能获得.
解决方案我们使用react-virtualized中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 ( <li key={key} style={style}> {list[index]} </li> ); } // Render your list ReactDOM.render( <List width={300} height={300} rowCount={list.length} rowHeight={20} rowRenderer={rowRenderer} />, document.getElementById('example'), );
其中rowHeight是每一行的高度,可以传入固定高度也可以传入function。每次子元素高度改变需要调用recomputeRowHeights方法,指定索引后重新计算行高度和偏移量。
具体实现const ImgHeightComponent = ({ imgUrl, onHeightReady, height, width }) => { const [style, setStyle] = useState({ height, width, display: 'block', }) const getImgWithAndHeight = (url) => { return new Promise((resolve, reject) => { var img = new Image() // 改变图片的src img.src = url let set = null const onload = () => { if (img.width || img.height) { //图片加载完成 clearInterval(set) resolve({ width: img.width, height: img.height }) } } set = setInterval(onload, 40) }) } useEffect(() => { getImgWithAndHeight(imgUrl).then((size) => { const currentHeight = size.height * (width / size.width) setStyle({ height: currentHeight, width: width, display: 'block', }) onHeightReady(currentHeight) }) }, []) return <img src={imgUrl} alt='' style={style} /> }
先写一个获取图片高度的组件,通过定时循环检测获取并计算出高度传给父组件。
import React, { useState, useEffect, useRef } from 'react' import styles from './index.scss' import { AutoSizer } from 'react-virtualized/dist/commonjs/AutoSizer' import { List } from 'react-virtualized/dist/commonjs/List' export default class DocumentStudy extends React.Component { constructor(props) { super(props) this.state = { list: [], heights: [], autoWidth:900, autoHeight: 300 } } handleHeightReady = (height, index) => { this.setState( (state) => { const flag = state.heights.some((item) => item.index === index) if (!flag) { return { heights: [ ...state.heights, { index, height, }, ], } } return { heights: state.heights, } }, () => { this.listRef.recomputeRowHeights(index) }, ) } getRowHeight = ({ index }) => { const row = this.state.heights.find((item) => item.index === index) return row ? row.height : this.state.autoHeight } renderItem = ({ index, key, style }) => { const { list, autoWidth, autoHeight } = this.state if (this.state.heights.find((item) => item.index === index)) { return ( <li key={key} style={style}> <img src={list[index].imgUrl} alt='' style={{width: '100%'}}/> </li> ) } return ( <li key={key} style={style}> <ImgHeightComponent imgUrl={list[index].imgUrl} width={autoWidth} height={autoHeight} onHeightReady={(height) => { this.handleHeightReady(height, index) }} /> </li> ) } render() { const { list } = this.state return ( <> <li style={{ height: 1000 }}> <AutoSizer> {({ width, height }) => ( <List ref={(ref) => (this.listRef = ref)} width={width} height={height} overscanRowCount={10} rowCount={list.length} rowRenderer={this.renderItem} rowHeight={this.getRowHeight} /> )} </AutoSizer> </li> </> ) } }
父组件通过handleHeightReady方法收集所有图片的高度,并在每一次高度改变调用List组件的recomputeRowHeights方法通知组件重新计算高度和偏移。到这里基本已经解决遇到的问题。
实际效果 小结目前只是使用react-virtualized来完成图片长列表实现,具体react-virtualized内部实现还需要进一步研究。
以上就是用react-virtualized实现图片动态高度长列表的详细内容,更多关于react virtualized长列表的资料请关注开心学习网其它相关文章!
您可能感兴趣
- react中state的作用是什么(React中useEffect 与 useLayoutEffect的区别)
- reactnative示例代码(React Native项目框架搭建的一些心得体会)
- react初学难点(使用react的7个避坑案例小结)
- react组件之间通信(React传递参数的几种方式)
- react的事件绑定(React事件绑定的方式详解)
- react循环有几种方法(React forwardRef的使用方法及注意点)
- react事件绑定的方式和区别(react合成事件与原生事件的相关理解)
- react加载优化(React星星评分组件的实现)
- react绑定详解(React列表栏及购物车组件使用详解)
- reactnative动态设置值(react native实现监控手势上下拉动效果)
- react路由组件怎么用(无废话快速上手React路由开发)
- react的动画实现(React实现动效弹窗组件)
- reactnative混合开发教程(教你使用vscode 搭建react-native开发环境)
- react实现js控制样式(React + Threejs + Swiper 实现全景图效果的完整代码)
- react 使用实例(React+高德地图实时获取经纬度,定位地址)
- react native常用组件(react native环境安装流程)
- 《满江红》不要只当电影看,学生应该这样做(满江红不要只当电影看)
- 电影《民间怪谈录之走阴人》定档8月5日,开启一场中式惊悚之旅(电影民间怪谈录之走阴人定档8月5日)
- 原创图画书,以儿童视角讲述中国故事(以儿童视角讲述中国故事)
- 八月再见 愿你岁月不扰,余生静好(八月再见愿你岁月不扰)
- 赏读 八月再见,九月你好(赏读八月再见九月你好)
- 散文 八月再见,九月,我在风中等你(散文八月再见九月)
热门推荐
- css子块级元素有用吗(css中行内元素和块级元素的区别)
- php 支付系统(php 实现银联商务H5支付的示例代码)
- linux查询服务重启(Linux上定位后台服务偶发崩溃的解决方法)
- asp.net中Server.MapPath的使用
- foot rocker怎么使用(stricky footer的三种解决方案详解)
- 前端轮播图效果(AmazeUI图片轮播效果的示例代码)
- dedecms系统参数设置(DedeCMS 5 .7 自定义表单制作和调用办法[图文])
- sqlserver表导入数据(在SQLserver数据库之间进行传表和传数据的图文教程)
- 搭建web服务器与设置(怎样在Win7系统中搭建Web服务器)
- laravel图文消息后台处理(laravel利用中间件防止未登录用户直接访问后台的方法)
排行榜
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9