使用 React 和 J*aScript 实现跨类别预测列表的键盘导航


使用 react 和 javascript 实现跨类别预测列表的键盘导航

本文档旨在提供一个清晰的指南,讲解如何在 React 应用中,处理多类别预测列表,并允许用户通过键盘上下键进行导航选择。核心思路是将多类别数据扁平化,利用 `useState` 管理选中项的索引,并通过 props 将选中状态传递给子组件,实现高亮显示。同时,强调了避免使用数组索引作为唯一ID的重要性,并提供完整的代码示例,方便读者理解和应用。

在 React 应用中,实现跨类别预测列表的键盘导航,需要考虑数据的组织形式、状态的管理以及组件间的通信。 本教程将详细介绍如何使用 React 和 J*aScript 来实现这一功能,并提供完整的代码示例。

1. 数据结构设计

首先,需要设计合理的数据结构。避免直接使用数组索引作为唯一标识符(ID),因为这可能导致后续维护和调试的困难。推荐为每个预测项和类别都分配一个唯一的 id 属性。

const prediction = {
    id: 1,
    name: "Hello, world!"
};

const category = {
    id: 1,
    name: "First category",
    predictions: [prediction]
};

2. 组件化方案

将应用拆分为三个核心组件:

  • gories>: 负责渲染类别列表,并管理全局的选中状态。
  • : 负责渲染单个类别及其包含的预测项。
  • </strong>: 负责渲染单个预测项,并根据是否被选中应用高亮样式。</li></ul><h3>3. 数据扁平化</h3><p>为了方便键盘导航,将多层嵌套的类别和预测项数据扁平化为一个一维数组。可以使用 J*aScript 的 flatMap 方法来实现。</p><pre class="brush:php;toolbar:false;">const Categories = ({ categories }) => {
        const allItems = categories.flatMap(x => x.predictions);
        // ...
    };

    4. 状态管理

    使用 React 的 useState Hook 来管理当前选中项的索引 selectedIndex。

    即梦AI 即梦AI

    一站式AI创作平台,免费AI图片和视频生成。

    即梦AI 16094 查看详情 即梦AI
    const Categories = ({ categories }) => {
        const allItems = categories.flatMap(x => x.predictions);
        const [selectedIndex, setSelectedIndex] = React.useState(0);
        const selectedItem = allItems[selectedIndex];
    
        // ...
    };

    selectedItem 存储了当前选中项的信息。

    5. 组件间通信

    将当前选中项的 id 通过 props 传递给子组件,以便它们能够判断自身是否被选中。

    // <Categories>
    {categories.map(x => <Category
        key={x.id}
        ...
        selectedId={selectedItem.id} />)}
    
    // <pre class="brush:php;toolbar:false;"diction>
    const Prediction = ({ id, name, selectedId }) => {
        const isSelected = id === selectedId;
        return <li className={isSelected ? "highlight" : ""}>{name}</li>;
    };

    6. 键盘事件处理

    在 组件上绑定 onKeyUp 事件,并根据按键类型更新 selectedIndex。需要进行边界检查,防止索引超出范围。

    const Categories = ({ categories }) => {
        // ...
    
        const onKeyUp = (event) => {
            switch (event.code) {
                case "ArrowUp":
                    setSelectedIndex(Math.max(0, selectedIndex - 1));
                    break;
                case "ArrowDown":
                    setSelectedIndex(
                        Math.min(allItems.length - 1, selectedIndex + 1)
                    );
                    break;
            }
        };
    
        return (<div onKeyUp={onKeyUp} tabIndex={-1}>
            ...
        </div>);
    };

    tabIndex="-1" 属性使得 div 元素可以接收键盘事件。

    7. 完整示例代码

    // Example data here.
    const teeShirts = [
        { id: 1, name: "Black" },
        { id: 2, name: "Red" },
        { id: 3, name: "Blue" },
    ];
    
    const accessories = [
        { id: 4, name: "Cool Cap" },
        { id: 5, name: "Fancy Tie" },
        { id: 6, name: "Medallion" },
    ];
    
    const countries = [
        { id: 7, name: "United Kingdom" },
        { id: 8, name: "United States" },
        { id: 9, name: "Australia" },
    ];
    
    const categories = [
        { id: 1, name: "T-Shirts", predictions: teeShirts },
        { id: 2, name: "Accessories", predictions: accessories },
        { id: 3, name: "Countries", predictions: countries },
    ];
    
    const Categories = ({ categories }) => {
        const allItems = categories.flatMap((x) => x.predictions);
        const [selectedIndex, setSelectedIndex] = React.useState(0);
        const selectedItem = allItems[selectedIndex];
    
        const onKeyUp = (event) => {
            switch (event.code) {
                case "ArrowUp":
                    setSelectedIndex(Math.max(0, selectedIndex - 1));
                    break;
                case "ArrowDown":
                    setSelectedIndex(
                        Math.min(allItems.length - 1, selectedIndex + 1)
                    );
                    break;
            }
        };
    
        return (
            <div onKeyUp={onKeyUp} tabIndex={-1}>
                {categories.map((category) => (
                    <Category
                        key={category.name}
                        id={category.id}
                        name={category.name}
                        predictions={category.predictions}
                        selectedId={selectedItem.id}
                    />
                ))}
            </div>
        );
    };
    
    const Category = ({ name, predictions, selectedId }) => {
        return (
            <div>
                {name}
                <ul role="listbox">
                    {predictions.map((prediction) => (
                        <pre class="brush:php;toolbar:false;"diction
                            key={prediction.name}
                            id={prediction.id}
                            name={prediction.name}
                            selectedId={selectedId}
                        />
                    ))}
                </ul>
            </div>
        );
    };
    
    const Prediction = ({ id, name, selectedId }) => {
        const isSelected = id === selectedId;
        return <li className={isSelected ? "highlight" : ""}>{name}</li>;
    };
    
    // This is just bootstrapping so the example works
    const App = () => {
        return <Categories categories={categories} />;
    };
    
    const root = ReactDOM.createRoot(document.getElementById("root"));
    root.render(
        <React.StrictMode>
            <App />
        </React.StrictMode>
    );
    .highlight {
      color: red;
      font-weight: bold;
    }
    <script src="https://cdnjs.cloudflare.com/ajax/libs/react/18.2.0/umd/react.development.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/18.2.0/umd/react-dom.development.js"></script>
    
    <div id="root"></div>

    总结

    通过以上步骤,可以实现一个支持键盘导航的跨类别预测列表。关键在于数据的扁平化、状态的管理以及组件间的通信。同时,需要注意避免使用数组索引作为唯一标识符,并进行边界检查,确保应用的稳定性和可靠性。 这个方法可以应用到各种需要键盘交互的列表型组件中,提高用户体验。

以上就是使用 React 和 J*aScript 实现跨类别预测列表的键盘导航的详细内容,更多请关注其它相关文章!


# 加载  # 永康谷歌seo公司  # 宜良营销推广找谁  # 合肥新华优阁营销推广  # 微小说网站建设  # 丰台网站推广优化  # 日照创意网站建设制作  # 淘宝刷粉网站推广便宜吗  # 正规seo软件优化  # 营销网站优化工作  # 青岛外链seo  # 解决问题  # 中文网  # 相关文章  # 这一  # react  # 表型  # 来实现  # 扁平化  # 自定义  # 数据结构  # switch  # access  # app  # go  # ajax  # bootstrap  # js  # java  # javascript 


相关栏目: 【 Google疑问12 】 【 Facebook疑问10 】 【 优化推广96088 】 【 技术知识133117 】 【 IDC资讯59369 】 【 网络运营7196 】 【 IT资讯61894 】


相关推荐: 苹果手机如何清理系统缓存数据 iPhone非越狱清理垃圾文件的技巧【系统优化】  Win11便笺在哪打开 Win11桌面便笺(Sticky Notes)使用方法【详解】  追剧达人如何发弹幕  B站怎么开|直播| B站|直播|申请需要什么条件【新手必看】  Sublime怎么自动添加CSS前缀_Sublime安装Autoprefixer插件  PHP动态导航按钮:根据用户登录状态切换链接与文本  J*aScript事件处理:优化键盘输入与表单提交的实践指南  Sublime Text怎么关闭自动完成_Sublime禁用Auto Complete设置  Windows Audio服务启动失败怎么办_电脑没声音的终极服务修复法【修复】  荣耀magicv5怎么上手测评  Win11怎么录屏_Windows 11自带Xbox Game Bar录制视频  《浙里办》电子发票开具方法  TikTok笔记文字无法编辑如何解决 TikTok笔记文字编辑优化方法  创建快捷方式启动系统保护  163邮箱在线登录 163邮箱网页版在线入口  《大周列国志》皇帝律令功能介绍  苹果如何下载nanobanana  《百度畅听版》关闭兴趣推荐方法  优化CSS动画与J*aScript定时器协同:构建稳定Toast提示  解决CSS容器溢出问题:使用calc()实现精确布局与边距控制  咸鱼怎么设置仅粉丝可见的动态_咸鱼动态粉丝可见设置方法  蛙漫2(台版)正版官网 2025免费网页版分享  如何用mysql实现客户反馈管理_mysql客户反馈数据库方法  win11怎么设置默认终端为Windows Terminal Win11替代CMD和PowerShell【技巧】  《花瓣》创建专辑方法  QQ网页版官方账号登录入口 QQ网页版网页版入口快速导航  哔哩哔哩黑名单怎么查看  Mac如何开启画中画模式_Mac Safari浏览器视频画中画功能  智慧团建活动报名入口 智慧团建活动报名入口手机端官网​  Win10关闭UAC用户账户控制的方法 Win10降低安全提示等级【技巧】  掌握Go App Engine项目结构与GOPATH:包管理与导入实践  OTT月报 | 2025年9月智能电视大数据报告  在Spring Boot Thymeleaf中利用布尔属性实现容器的条件显示  Vue 3中独立响应式实例的创建与应用  大众点评了却看不到是怎么回事  雨课堂官网在线登录 网页版雨课堂登录链接  如何在CSS中清除浮动解决背景颜色不包裹内容问题_clear after技巧  windows server2019显卡驱动怎么安装_winserver2019显卡驱动安装与远程桌面优化  b站如何剪辑视频_b站必剪app使用教程  使用jQuery精确检测除指定元素外任意位置的点击事件  天堂漫画网页版在线阅读 天堂漫画手机版入口  TikTok私信无法发送表情怎么办 TikTok消息表情发送修复方法  《大润发优鲜》充值方法介绍  《新三国志曹操传》游历事件袁尚突围攻略  解决SQLAlchemy模型跨文件关联的Linter兼容性指南  Python自动化抓取GBGB赛狗比赛结果:日期范围与赛道筛选教程  Python中对象引用与链表属性赋值的机制解析  火柴人战争网页版在线玩  如何在 WordPress 前端实现内容提交:古腾堡编辑器的替代方案与实践  猫眼电影app如何参与官方的抽奖活动_猫眼电影官方抽奖参与方法 

 2025-11-16

了解您产品搜索量及市场趋势,制定营销计划

同行竞争及网站分析保障您的广告效果

点击免费数据支持

提交您的需求,1小时内享受我们的专业解答。

运城市盐湖区信雨科技有限公司


运城市盐湖区信雨科技有限公司

运城市盐湖区信雨科技有限公司是一家深耕海外推广领域十年的专业服务商,作为谷歌推广与Facebook广告全球合作伙伴,聚焦外贸企业出海痛点,以数字化营销为核心,提供一站式海外营销解决方案。公司凭借十年行业沉淀与平台官方资源加持,打破传统外贸获客壁垒,助力企业高效开拓全球市场,成为中小企业出海的可靠合作伙伴。

 8156699

 13765294890

 8156699@qq.com

Notice

We and selected third parties use cookies or similar technologies for technical purposes and, with your consent, for other purposes as specified in the cookie policy.
You can consent to the use of such technologies by closing this notice, by interacting with any link or button outside of this notice or by continuing to browse otherwise.