1. 高阶组件之 AutoSizer 由于List组件本身没有铺满全屏的功能 所以需要使用AutoSizer组件辅助实现
(AutoSizer 同样出自于 react-virtualized)
1-1 AutoSizer内部使用箭头函数并将参数 width, height 结构出来 在函数内部将width 和 height 赋值给 List组件的 width height
1-2 AutoSizer 实现铺满全屏的功能 要求父元素的高度铺满全屏 所以要给父盒子 heigth: 100%;
2. List
2-1 事件:rowRenderer 接受一个jsx 将其渲染为长列表 绑定一个长列表渲染函数返回jsx
函数自带参数{
key, //diff算法用的
index, // 索引
isScrolling, // 当前项是否在滚动
isVisible, // 当前行是否可见
style // 每一行都要有的样式 指定每一行的位置
}
2-2 属性 rowHeight 每一行的高度 可接受 number | function
传number 就会让每一行的高度一样高
如果每一行的高度不确定 就需要 函数来处理 函数参数可以结构出来({index})代表当前行的索引
返回值必须是一个 number
2-3 属性rowCount 代表有多少行
2-4 属性width height 组件List的宽和高 接受值 number
2-5 事件onRowsRendered 当列表渲染新行的时候 函数中可以解构出来 ({startIndex,stopIndex}) 当前列表顶部和底部行的索引值 也就是说 每当列表开始滚动时 我们都可以拿到当前顶部和底部的索引
3. 索引
1-1 首先索引是否高亮需要一个状态来控制 actIndex
1-2 长列表滚动时 对应索引高亮
onRowsRendered事件 解构出startIndex 如果startIndex !== actIndex 更新状态 actIndex
1-3 点击索引时 列表滚动到指定位置
给每一个索引添加一个点击事件
需要用到List组件的方法 scrollToRow(index:要移动到的位置索引值)
所以还需要先获取到 List 的ref
在react中引入 createRef
组件中声明listRef = createRef<any>()
this.listRef.current.scrollToRow(index)
1-4 此时点击索引时能工作 但是该索引在列表位置不是从头开始的 想要在页面顶部 需要加上属性
scrollToAlignment='start' (默认 auto: 让选中行尽可能的全部显示在屏幕 start:选中行在顶部 center: 选中行在中间 end : 选中行在底部)
1-5 此时 点击索引列表滚动的距离不准确 因为scrollToRow方法正常工作的一个前提是列表先曾被渲染过 所以 第一次点击靠后的索引时 位置错乱
解决办法:在滚动之前 计算好总高度
使用 List组件实例的measureAllRows() 在滚动前计算好高度
也就是在componentDidMount钩子中getCityList() 方法之后 计算总高度
出现问题:控制台报错 error计算-1长度失败
原因:getCityList() 异步方法 执行计算长度方法是 数据还没有获取到
解决:使用async await 钩子函数也能用async