react使用react-window虚拟滚动实战

摘要:react-window插件一般用来和react-virtualized-auto-sizer配合使用,react-virtualized-auto-sizer负责获取父元素的宽度和高度,传入到List中,但实战时,往往有些列表用到了隐藏显示, 比方说disabled:none;当使用disabled为none时,react-virtualized-auto-sizer会移除子元素;当返回时,元素会重新渲染,滚动条也会滚到顶部;

备注:如果是’visibility: hidden;'子元素会保留,其仍然占用宽度和高度,实战中很多场景不适用,这里不展开讨论;本文主要讲自定义AutoSizer组件规避掉disabled:none的Bug;

项目依赖
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-window": "^1.8.9",
// 实用这个有bug所以自己封装了AutoSizer
"react-virtualized-auto-sizer": "^1.0.20",
日常使用
import AutoSizer from "@/views/Components/AzAutoSizer";
<AutoSizer>
    {({ height, width }: {height: number, width: number}) => (
        <List 
            height={height}
            itemCount={curMonitorList.length}
            itemSize={48}
            width={width}>
            {renderOrgItem}
        </List>
        )
    }
</AutoSizer>
封装AutoSizer
import { useEffect, useState, useRef } from "react";
interface PropsType{
    children: any
}
export default function AzAutoSizer({children}: PropsType) {
    const curRef = useRef<HTMLDivElement>(null)
    const [curWidthHeight, setCurWidthHeight] = useState({
        height: 0,
        width: 0,
    });
    const handleClick = () => {
        if (curRef.current) {
            const parentNode: any = curRef.current.parentNode;
            const height = parentNode.offsetHeight;
            const width = parentNode.offsetWidth;
            curWidthHeight.height = height || 0;
            curWidthHeight.width = width || 0;
            setCurWidthHeight({...curWidthHeight});
        }
    };
    useEffect(() => {
        handleClick();
        const handleResize = () => {
            if (!curRef.current) { return; }
            // const parentNode: any = curRef.current.parentNode;
            // const height = parentNode.offsetHeight
            // const width = parentNode.offsetWidth;
            // // 表示父或祖先disabled: none;
            // if (height === 0 && width === 0) {
            //     return;
            // }
            handleClick();
        };
        /* 窗口改变 */
        window.addEventListener('resize', handleResize);
        /* 是否可视化 */
        const observer = new IntersectionObserver(([{ isIntersecting }]) => {
            if (isIntersecting) {
                if (!curRef.current) { return; }
                if (curWidthHeight.height !== 0 && curWidthHeight.width !== 0) {
                    // observer.unobserve(curRef.current);
                } else {
                    console.log('可视化');
                    handleClick();
                }
            }
        });
        curRef.current && observer.observe(curRef.current);

        return () => {
            /* 窗口改变 */
            window.removeEventListener('resize', handleResize);
            /* 卸载 */
            if (curRef.current) {
                observer.unobserve(curRef.current);
            }

        };

    }, []);
    return <div ref={curRef} style={{width: `${curWidthHeight.width}px`, height: `${ curWidthHeight.height}px`}}>
        {children({height: curWidthHeight.height, width: curWidthHeight.width})}
    </div>
}
  • 20
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
React-virtualized是一个非常流行的React库,它可以帮助我们实现大数据量的虚拟滚动效果。下面是一个使用React-virtualized实现虚拟滚动的表格的示例代码: 首先,我们需要安装React-virtualized库: ``` npm install react-virtualized --save ``` 然后,我们需要引入Table和Column组件: ``` import { Table, Column } from 'react-virtualized'; ``` 接下来,我们可以定义一个数据源,例如: ``` const list = [ { name: '张三', age: '18', address: '北京市海淀区' }, { name: '李四', age: '20', address: '北京市朝阳区' }, { name: '王五', age: '22', address: '北京市西城区' }, // ... // 这里可以添加更多的数据 ]; ``` 然后,我们可以定义一个Table组件,指定它的rowCount和rowGetter属性: ``` <Table rowCount={list.length} rowGetter={({ index }) => list[index]} > ``` 接下来,我们可以添加一些Column组件,定义每一列的属性: ``` <Column label="姓名" dataKey="name" width={100} /> <Column label="年龄" dataKey="age" width={100} /> <Column label="地址" dataKey="address" width={200} /> ``` 最后,我们需要在Table组件中添加一些属性,以启用虚拟滚动: ``` <Table rowCount={list.length} rowGetter={({ index }) => list[index]} headerHeight={20} rowHeight={30} width={600} height={400} > ``` 在上面的代码中,我们设置了headerHeight和rowHeight属性来指定表头和每一行的高度,width和height属性用于指定表格的宽度和高度。React-virtualized会自动根据这些属性来计算出需要渲染的行数,并且只渲染当前可见的行,以实现虚拟滚动的效果。 完整的代码示例: ``` import React, { Component } from 'react'; import { Table, Column } from 'react-virtualized'; const list = [ { name: '张三', age: '18', address: '北京市海淀区' }, { name: '李四', age: '20', address: '北京市朝阳区' }, { name: '王五', age: '22', address: '北京市西城区' }, // ... // 这里可以添加更多的数据 ]; class VirtualTable extends Component { render() { return ( <Table rowCount={list.length} rowGetter={({ index }) => list[index]} headerHeight={20} rowHeight={30} width={600} height={400} > <Column label="姓名" dataKey="name" width={100} /> <Column label="年龄" dataKey="age" width={100} /> <Column label="地址" dataKey="address" width={200} /> </Table> ); } } export default VirtualTable; ```

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值