前端组件库 ——React Aria 知识点大全(三)

简介: 教程来源 http://xcfsr.cn React Aria 提供集合组件(列表框、表格、虚拟滚动)与拖拽排序能力,均深度集成无障碍支持:`useListBox`/`useTable`确保键盘导航与ARIA语义,`useVirtualizer`优化大数据渲染性能,`useDrag`/`useDrop`实现可访问的拖放交互。

四、集合组件

React Aria 提供了一套强大的集合组件系统,用于处理列表、表格、树等结构化数据。

4.1 useListBox - 列表框
useListBox 用于创建可访问的列表框,支持单选/多选、键盘导航等。通常与 useListBoxSection 和 useOption 结合使用。

import { useListBox, useOption } from 'react-aria';
import { useListState } from 'react-stately';

function ListBox(props) {
    let state = useListState(props);
    let ref = useRef(null);
    let { listBoxProps } = useListBox(props, state, ref);

    return (
        <ul {...listBoxProps} ref={ref} style={
  {
            margin: 0,
            padding: '8px 0',
            listStyle: 'none',
            border: '1px solid #ccc',
            borderRadius: '4px',
            background: 'white',
            width: '200px'
        }}>
            {[...state.collection].map(item => (
                <Option key={item.key} item={item} state={state} />
            ))}
        </ul>
    );
}

function Option({ item, state }) {
    let ref = useRef(null);
    let { optionProps, isSelected, isFocused } = useOption({ key: item.key }, state, ref);

    return (
        <li {...optionProps} ref={ref} style={
  {
            padding: '8px 12px',
            background: isSelected ? '#007bff' : isFocused ? '#f0f0f0' : 'transparent',
            color: isSelected ? 'white' : 'black',
            cursor: 'pointer'
        }}>
            {item.rendered}
        </li>
    );
}

4.2 useTable - 表格组件
http://htnus.cn
useTable 系列 Hooks(useTable、useTableColumnHeader、useTableRow、useTableCell)用于创建可访问的数据表格,支持列排序、选择、键盘导航等高级功能。

import { useTable, useTableColumnHeader, useTableRow, useTableCell } from 'react-aria';
import { useTableState } from 'react-stately';

function Table(props) {
    let state = useTableState(props);
    let ref = useRef(null);
    let { gridProps } = useTable(props, state, ref);

    return (
        <div style={
  { overflow: 'auto' }}>
            <table {...gridProps} ref={ref} style={
  { borderCollapse: 'collapse', width: '100%' }}>
                <thead>
                    <tr>
                        {[...state.collection.headerRows].map(headerRow => (
                            <TableRow key={headerRow.key} item={headerRow} state={state} isHeader />
                        ))}
                    </tr>
                </thead>
                <tbody>
                    {[...state.collection.body].map(row => (
                        <TableRow key={row.key} item={row} state={state} />
                    ))}
                </tbody>
            </table>
        </div>
    );
}

function TableRow({ item, state, isHeader }) {
    let ref = useRef(null);
    let { rowProps } = useTableRow({ node: item }, state, ref);

    return (
        <tr {...rowProps} ref={ref}>
            {[...item.childNodes].map(column => (
                isHeader
                    ? <TableHeaderColumn key={column.key} column={column} state={state} />
                    : <TableCell key={column.key} column={column} state={state} />
            ))}
        </tr>
    );
}

function TableHeaderColumn({ column, state }) {
    let ref = useRef(null);
    let { columnHeaderProps } = useTableColumnHeader({ node: column }, state, ref);

    return (
        <th {...columnHeaderProps} ref={ref} style={
  { borderBottom: '2px solid #ccc', padding: '12px', textAlign: 'left' }}>
            {column.rendered}
        </th>
    );
}

function TableCell({ column, state }) {
    let ref = useRef(null);
    let { gridCellProps } = useTableCell({ node: column }, state, ref);

    return (
        <td {...gridCellProps} ref={ref} style={
  { borderBottom: '1px solid #eee', padding: '12px' }}>
            {column.rendered}
        </td>
    );
}

4.3 useVirtualizer - 虚拟滚动
在处理大量数据时,useVirtualizer 可以显著提升性能,只渲染视口内的内容。

import { useTable, useVirtualizer } from 'react-aria';
import { useTableState } from 'react-stately';

function VirtualTable(props) {
    let state = useTableState(props);
    let ref = useRef(null);
    let { gridProps } = useTable(props, state, ref);

    // 计算行高和可见范围
    let rowHeight = 48;
    let rows = [...state.collection.body];
    let totalHeight = rows.length * rowHeight;

    // 根据滚动位置计算可见行
    let isScrolling = useVirtualizer();
    let [scrollTop, setScrollTop] = useState(0);
    let startIndex = Math.floor(scrollTop / rowHeight);
    let endIndex = Math.min(startIndex + Math.ceil(ref.current?.clientHeight / rowHeight) + 5, rows.length);
    let visibleRows = rows.slice(startIndex, endIndex);
    let offsetY = startIndex * rowHeight;

    const handleScroll = (e) => {
        setScrollTop(e.currentTarget.scrollTop);
    };

    return (
        <div ref={ref} onScroll={handleScroll} style={
  { height: 400, overflow: 'auto' }}>
            <div {...gridProps} style={
  { position: 'relative', height: totalHeight }}>
                <div style={
  { position: 'absolute', top: offsetY, left: 0, right: 0 }}>
                    <tr>
                        {visibleRows.map(row => (
                            <TableRow key={row.key} item={row} state={state} />
                        ))}
                    </tbody>
                </div>
            </div>
        </div>
    );
}

五、拖拽与排序

React Aria 提供了完整的拖拽支持,包括拖拽源、放置目标、拖拽预览等。useDrag 和 useDrop 是核心的基础 Hooks。

5.1 useDrag - 拖拽源

import { useDrag } from 'react-aria';

function DraggableItem({ item }) {
    let ref = useRef(null);
    let { dragProps, isDragging } = useDrag({
        getItems: () => [{ 'text/plain': item.name }],
        onDragStart: () => console.log('拖拽开始'),
        onDragEnd: () => console.log('拖拽结束')
    });

    return (
        <div ref={ref} {...dragProps} style={
  {
            padding: '8px 12px',
            margin: '4px',
            background: isDragging ? '#e0e0e0' : '#f5f5f5',
            border: '1px solid #ccc',
            borderRadius: '4px',
            cursor: 'grab',
            opacity: isDragging ? 0.5 : 1
        }}>
            {item.name}
        </div>
    );
}

5.2 useDrop - 放置目标

import { useDrop } from 'react-aria';

function DropZone({ onDrop }) {
    let ref = useRef(null);
    let { dropProps, isDropTarget } = useDrop({
        onDrop: async (e) => {
            let items = await Promise.all(
                e.items
                    .filter(item => item.kind === 'string' && item.types.has('text/plain'))
                    .map(item => item.getText('text/plain'))
            );
            onDrop(items);
        }
    });

    return (
        <div ref={ref} {...dropProps} style={
  {
            padding: '100px',
            border: `2px dashed ${isDropTarget ? '#007bff' : '#ccc'}`,
            borderRadius: '8px',
            textAlign: 'center',
            background: isDropTarget ? '#f0f8ff' : 'white'
        }}>
            拖拽文件或元素到这里
        </div>
    );
}
相关文章
|
5月前
|
缓存 弹性计算 Linux
阿里云服务器e实例2核2G99元1年,u1实例2核4G199元怎么样?性能与适用场景解析
阿里云推出的云服务器低价长效特惠活动,主打经济型e实例(99元/年)和通用算力型u1实例(199元/年)。经济型e实例适合个人开发者、学生及小微企业,提供基础算力,满足轻量级应用需求。通用算力型u1实例面向企业用户,性能更稳定,适合企业级应用。此外,阿里云目前还有轻量应用服务器抢购活动,提供2核2G和2核4G配置,价格低至38元/年和9.9元/月起,满足不同用户需求。
577 1
|
8月前
|
存储 机器学习/深度学习 算法
交易所平台系统开发:关键功能与技术剖析
本文深入解析交易所平台系统架构与核心功能,涵盖分层设计、微服务架构及容器化部署方案,重点探讨交易撮合引擎与风控系统的技术实现,为开发者提供高性能、高可用的系统开发参考框架。
|
11月前
|
人工智能 搜索推荐 Cloud Native
拔俗AI助教系统:教师的"超级教学秘书",让每堂课都精准高效
备课到深夜、批改作业如山?阿里云原生AI助教系统,化身“超级教学秘书”,智能备课、实时学情分析、自动批改、精准辅导,为教师减负增效。让课堂从经验驱动转向数据驱动,每位学生都被看见,教育更有温度。
957 0
|
XML Java Android开发
34. 【Android教程】菜单:Menu
34. 【Android教程】菜单:Menu
966 2
|
关系型数据库 MySQL 网络安全
关于对连接数据库时出现1130-host “**” is not allowed to connect to this MySql/mariadb server
关于对连接数据库时出现1130-host “**” is not allowed to connect to this MySql/mariadb server
866 0
|
存储 搜索推荐 算法
Java 大视界 -- Java 大数据在智慧文旅旅游线路规划与游客流量均衡调控中的应用实践(196)
本实践案例深入探讨了Java大数据技术在智慧文旅中的创新应用,聚焦旅游线路规划与游客流量调控难题。通过整合多源数据、构建用户画像、开发个性化推荐算法及流量预测模型,实现了旅游线路的精准推荐与流量的科学调控。在某旅游城市的落地实践中,游客满意度显著提升,景区流量分布更加均衡,充分展现了Java大数据技术在推动文旅产业智能化升级中的核心价值与广阔前景。
|
机器人 API 数据安全/隐私保护
QQ机器人插件源码,自动回复聊天机器人,python源码分享
消息接收处理:通过Flask搭建HTTP服务接收go-cqhttp推送的QQ消息47 智能回复逻辑
|
人工智能 前端开发 API
手动开发?给我一条提示词,CodeBuddy能做的你都做不到!
本文介绍了使用CodeBuddy完成的一个五一期间的小项目,主要展示其编码能力。项目采用基础的HTML+CSS+JS实现界面,也提到可用React或Next.js复刻。文章重点讲解了通过提示词生成代码的方法,包括局部和整体两种方式,并展示了AI旅行规划功能的实现过程。通过与模型对话调整细节,最终生成满意的界面。CodeBuddy在前后端开发中表现出强大能力,未来可结合绘画作品生成惊艳网站。
631 1
解决ERROR in Conflict: Multiple assets emit different content to the same filename index.html 的问题
解决ERROR in Conflict: Multiple assets emit different content to the same filename index.html 的问题
1456 1
|
存储 缓存 Java
c++的哈希表、哈希桶的介绍与实现
这一篇文章大致实现详细介绍什么是哈希,然后再介绍什么是哈希表,怎么代码实现哈希表,然后再介绍哈希桶,怎么代码实现哈希桶,最后再介绍他俩有什么细节上的差别,与代码的一些细节优化。
471 0

热门文章

最新文章