前端组件库 ——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>
    );
}
相关文章
|
12天前
|
人工智能 JSON 供应链
畅用7个月无影 JVS Claw |手把手教你把JVS改造成「科研与产业地理情报可视化大师」
LucianaiB分享零成本畅用JVS Claw教程(学生认证享7个月使用权),并开源GeoMind项目——将JVS改造为科研与产业地理情报可视化AI助手,支持飞书文档解析、地理编码与腾讯地图可视化,助力产业关系图谱构建。
23475 11
畅用7个月无影 JVS Claw |手把手教你把JVS改造成「科研与产业地理情报可视化大师」
|
16天前
|
人工智能 缓存 BI
Claude Code + DeepSeek V4-Pro 真实评测:除了贵,没别的毛病
JeecgBoot AI专题研究 把 Claude Code 接入 DeepSeek V4Pro,跑完 Skills —— OA 审批、大屏、报表、部署 5 大实战场景后的真实体验 ![](https://oscimg.oschina.net/oscnet/up608d34aeb6bafc47f
5236 19
Claude Code + DeepSeek V4-Pro 真实评测:除了贵,没别的毛病
|
17天前
|
人工智能 JSON BI
DeepSeek V4 来了!超越 Claude Sonnet 4.5,赶紧对接 Claude Code 体验一把
JeecgBoot AI专题研究 把 Claude Code 接入 DeepSeek V4Pro 的真实体验与避坑记录 本文记录我将 Claude Code 对接 DeepSeek 最新模型(V4Pro)后的真实体验,测试了 Skills 自动化查询和积木报表 AI 建表两个场景——有惊喜,也踩
6253 15
|
6天前
|
人工智能 缓存 Shell
Claude Code 全攻略:命令大全 + 实战工作流(完整版)
Claude Code 是一款运行在终端环境下的 AI 编码助手,能够直接在项目目录中理解代码结构、编辑文件、执行命令、执行开发计划,并支持持久化记忆、上下文压缩、后台任务、多模型切换等专业能力。对于日常开发、项目维护、快速重构、代码审查等场景,它可以大幅减少手动操作、提升编码效率。本文从常用命令、界面模式、核心指令、记忆机制、图片处理、进阶工作流等维度完整说明,帮助开发者快速上手并稳定使用。
1306 2
|
5天前
|
前端开发 API 内存技术
对比claude code等编程cli工具与deepseek v4的适配情况
DeepSeek V4发布后,多家编程工具因未适配其强制要求的`reasoning_content`字段而报错。本文对比Claude Code、GitHub Copilot、Langcli、OpenCode及DeepSeek-TUI等主流工具的兼容性:Claude Code需按官方方式配置;Langcli表现最佳,开箱即用且无报错;Copilot与OpenCode暂未修复问题;DeepSeek-TUI尚处早期阶段。
949 2
对比claude code等编程cli工具与deepseek v4的适配情况
|
1月前
|
人工智能 自然语言处理 安全
Claude Code 全攻略:命令大全 + 实战工作流(建议收藏)
本文介绍了Claude Code终端AI助手的使用指南,主要内容包括:1)常用命令如版本查看、项目启动和更新;2)三种工作模式切换及界面说明;3)核心功能指令速查表,包含初始化、压缩对话、清除历史等操作;4)详细解析了/init、/help、/clear、/compact、/memory等关键命令的使用场景和语法。文章通过丰富的界面截图和场景示例,帮助开发者快速掌握如何通过命令行和交互界面高效使用Claude Code进行项目开发,特别强调了CLAUDE.md文件作为项目知识库的核心作用。
26208 65
Claude Code 全攻略:命令大全 + 实战工作流(建议收藏)