在React中通过HTML数据属性传递映射数组数据


在react中通过html数据属性传递映射数组数据

本教程旨在解决在React中将映射数组的数据附加到原生HTML元素(如

  • )并从事件处理函数中访问的问题。我们将深入探讨为什么直接使用自定义HTML属性会失败,并详细介绍如何利用HTML5的data-属性来安全、有效地存储和检索这些数据,同时提供示例代码和最佳实践。

    理解原生HTML元素与自定义属性的限制

    在React中,当您渲染一个原生HTML元素(例如

    , ,
  • 等)时,React会将其转换为真实的DOM元素。这些原生HTML元素只识别标准的HTML属性。如果您尝试直接附加非标准的自定义属性,例如在以下代码片段中尝试的airport、lat、name和long:
    <li
      key={airport.iata}
      airport={airport} // 非标准属性
      onClick={handleLiClickFirst}
      lat={airport.latitude} // 非标准属性
      name={airport.name}   // 非标准属性
      long={airport.longitude} // 非标准属性
    >
      {airport.name}
    </li>

    这些非标准属性并不会被DOM视为可访问的数据属性。当事件(如onClick)触发时,您通过event.target访问到的DOM元素将不会包含这些属性,因此尝试通过event.target.lat等方式获取数据会失败,返回undefined。

    const handleLiClickFirst = (airport) => {
        // airport.target.lat 将是 undefined
        console.log(airport.target.lat);
    };

    这是因为React在渲染原生HTML元素时,会过滤掉它不认识的属性,以保持DOM的整洁和符合标准。

    使用HTML5数据属性(Data Attributes)解决问题

    为了将自定义数据附加到HTML元素上,HTML5引入了数据属性(Data Attributes)。数据属性以data-前缀开头,后跟自定义的名称,例如data-latitude、data-airport-name等。浏览器会识别这些属性,并将其存储在元素的dataset属性中,从而允许J*aScript安全地访问它们。

    1. 附加数据属性

    在React中,您可以像传递普通属性一样,将数据属性附加到原生HTML元素上。请确保属性名遵循data-your-custom-name的格式。

    <li
      key={airport.iata}
      // 使用data-属性来存储数据
      data-iata={airport.iata}
      data-latitude={airport.latitude}
      data-longitude={airport.longitude}
      data-name={airport.name}
      // 如果需要传递整个对象,可以将其JSON字符串化
      data-airport-data={JSON.stringify(airport)}
      onClick={handleLiClickFirst}
    >
      {airport.name}
    </li>

    注意事项:

    • 命名规范: data-后的属性名可以使用小写字母、数字、连字符(-)。在J*aScript中访问时,连字符会被转换为驼峰命名法(例如data-airport-name在J*aScript中是dataset.airportName)。
    • 数据类型: 数据属性的值始终是字符串。如果您存储的是数字、布尔值或对象,您需要在检索时进行类型转换(例如parseInt(), JSON.parse())。
    • 复杂对象: 如果需要存储整个J*aScript对象,您必须先使用JSON.stringify()将其转换为JSON字符串。

    2. 从事件处理函数中访问数据

    当事件触发时,您可以通过event.target.dataset对象来访问这些数据属性。dataset对象会包含所有以data-开头的属性,属性名将自动从连字符命名法转换为驼峰命名法。

    即梦AI 即梦AI

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

    即梦AI 16094 查看详情 即梦AI

    以下是修改后的handleLiClickFirst函数示例:

    const handleLiClickFirst = (event) => {
        // event.target 指向触发事件的 <li> 元素
        const targetLi = event.target;
    
        // 从 dataset 中获取数据
        const iata = targetLi.dataset.iata;
        const latitude = parseFloat(targetLi.dataset.latitude); // 转换为数字
        const longitude = parseFloat(targetLi.dataset.longitude); // 转换为数字
        const name = targetLi.dataset.name;
    
        console.log("IATA:", iata);
        console.log("Latitude:", latitude);
        console.log("Longitude:", longitude);
        console.log("Name:", name);
    
        // 如果存储了整个对象,需要JSON.parse()解析
        if (targetLi.dataset.airportData) {
            try {
                const airportObject = JSON.parse(targetLi.dataset.airportData);
                console.log("Full Airport Object:", airportObject);
                // 您可以使用这个对象来更新状态或其他逻辑
                setFirst(airportObject.name); // 例如,更新状态为机场名称
            } catch (e) {
                console.error("Error parsing airport data:", e);
            }
        } else {
            setFirst(name); // 如果没有完整对象,则使用单独的名称
        }
    };

    3. 完整示例代码

    结合上述修改,您的React组件代码将如下所示:

    import React, { useState, useEffect } from 'react';
    import { TextField } from '@mui/material'; // 假设您使用的是MUI组件
    
    // 模拟数据,实际应用中可能来自API
    const mockAirports = [
      { iata: 'JFK', name: 'John F. Kennedy International Airport', latitude: 40.6413, longitude: -73.7781 },
      { iata: 'LAX', name: 'Los Angeles International Airport', latitude: 33.9416, longitude: -118.4085 },
      { iata: 'ORD', name: 'O\'Hare International Airport', latitude: 41.9742, longitude: -87.9073 },
    ];
    
    function AirportSelector() {
      const [first, setFirst] = useState('');
      const [resultFirst, setResultFirst] = useState({ airports: [] });
    
      useEffect(() => {
        // 模拟数据过滤
        if (first) {
          const filtered = mockAirports.filter(airport =>
            airport.name.toLocaleLowerCase().includes(first) ||
            airport.iata.toLocaleLowerCase().includes(first)
          );
          setResultFirst({ airports: filtered });
        } else {
          setResultFirst({ airports: mockAirports }); // 或清空
        }
      }, [first]);
    
      const handleLiClickFirst = (event) => {
        const targetLi = event.target;
        const name = targetLi.dataset.name;
        const iata = targetLi.dataset.iata;
        const latitude = parseFloat(targetLi.dataset.latitude);
        const longitude = parseFloat(targetLi.dataset.longitude);
    
        console.log("Selected Airport Details:");
        console.log("Name:", name);
        console.log("IATA:", iata);
        console.log("Latitude:", latitude);
        console.log("Longitude:", longitude);
    
        setFirst(name); // 更新TextField的值为选中的机场名称
        setResultFirst({ airports: [] }); // 清空列表
      };
    
      return (
        <div className="header__first">
          <TextField
            id="outlined-basic"
            label="From"
            variant="outlined"
            value={first}
            onChange={(e) => setFirst(e.target.value.toLocaleLowerCase())}
          />
          <ul>
            {resultFirst.airports?.map((airport) => {
              return (
                <li
                  key={airport.iata}
                  // 使用data-属性传递数据
                  data-iata={airport.iata}
                  data-latitude={airport.latitude}
                  data-longitude={airport.longitude}
                  data-name={airport.name}
                  onClick={handleLiClickFirst}
                >
                  {airport.name}
                </li>
              );
            })}
          </ul>
        </div>
      );
    }
    
    export default AirportSelector;

    最佳实践与替代方案

    虽然数据属性是解决此类问题的有效方法,但在某些情况下,还有其他更符合React范式的方法值得考虑:

    1. 避免存储整个对象: 尽量只存储您需要访问的最小数据单元(如ID、名称、坐标)。将整个复杂对象JSON.stringify到数据属性中可能会导致HTML属性字符串过长,增加DOM大小,并带来额外的序列化/反序列化开销。

    2. 直接传递数据到事件处理函数: 如果您不需要将数据实际存储在DOM元素上,而是仅仅在事件触发时需要访问它,那么最直接且React-idiomatic的方式是直接将数据作为参数传递给事件处理函数。

      // 在map中
      <li
        key={airport.iata}
        onClick={() => handleLiClickFirst(airport)} // 直接传递airport对象
      >
        {airport.name}
      </li>
      
      // 事件处理函数
      const handleLiClickFirst = (selectedAirport) => {
        console.log("Selected Airport Object:", selectedAirport);
        setFirst(selectedAirport.name);
        // ... 其他逻辑
      };

      这种方法更简洁,避免了DOM操作,并且直接处理J*aScript对象,无需进行字符串化和解析。然而,如果您的需求是必须通过HTML属性来传递数据(例如,为了CSS选择器或其他非React的J*aScript逻辑),那么data-属性仍然是首选。

    总结

    当需要在React中将自定义数据附加到原生HTML元素并从事件处理函数中访问时,data-属性是标准且推荐的解决方案。它们允许您将字符串数据嵌入到HTML中,并通过event.target.dataset对象轻松检索。虽然直接将数据传递给事件处理函数在许多React场景中更为简洁和高效,但了解并正确使用data-属性对于处理特定需求或与传统J*aScript交互的场景至关重要。始终优先考虑存储最小必要数据,并注意数据类型的转换。

  • 以上就是在React中通过HTML数据属性传递映射数组数据的详细内容,更多请关注其它相关文章!


    # 您可以  # 阳江网站建设推广价格  # seo及sem  # 专业网站seo优化报价  # 农村化肥怎么营销推广  # 宁波本地seo推广企业  # 百度怎样免费推广网站  # 网站推广应询a金脉科技  # 天蝎网站推广优化设计  # 乌当区花果园网站建设  # 滦县专业的网站优化  # 解决问题  # 或其他  # 您的  # 的是  # 将其  # css  # 如果您  # 非标准  # 转换为  # 自定义  # css选  # ai  # 浏览器  # html5  # json  # git  # js  # html  # java  # javascript  # react 


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


    相关推荐: 利用Flexbox实现图片元素的二维布局:2x2网格排列指南  C++ bind函数使用教程_C++参数绑定与函数适配器的应用  解决PHP MySQL数据库更新无响应:SQL查询语法错误解析  iQOO手机信号差网络不稳定怎么办 信号问题原因排查与增强设置【攻略】  KFC邀请码怎么使用领额外优惠_KFC邀请码输入方式与额外优惠代码获取方法  《华夏千秋》龙女试炼功法获取方法  Go Goroutine调度与并发执行深度解析  如何使用 Optional 类型并满足 Pylint 的类型检查  c++20的指定初始化(Designated Initializers)怎么用_c++ C风格结构体初始化  b站怎么用微信登录_b站微信登录方法  FotoBalloon图片左右镜像教程  C++中的explicit关键字有什么作用_C++类型转换控制与explicit使用  企查查官网和爱企查 企查查企业查询官网入口  画质怪兽120帧安卓和平精英免费版  pubmed数据库官方主页_pubmed学术论文查找官网直达  Python中安全地将环境变量转换为整数的类型注解指南  汽水音乐网页端访问 汽水音乐官方网页直达  美发店速赢秘籍  稻壳阅读器官方直达网址链接 稻壳阅读器文档阅读平台主页资源入口  使用 J*aScript 随机化 CSS Grid 布局中的元素顺序  《盗墓笔记手游》技能介绍  豆包AI怎样为教育场景定制答疑逻辑_为教育场景定制豆包AI答疑逻辑方案【方案】  性能与资源监视器快捷打开  Go Template中优雅处理循环最后一项:自定义函数实践  AffinityDesigner图层蒙版怎么用_AffinityDesigner图层蒙版设计应用  《单词速记宝》设置学习计划方法  C++ priority_queue怎么用_C++优先队列底层实现与自定义比较器  CSS布局中意外顶部空白的调试与解决:深入理解padding-top  C++如何实现矩阵乘法_C++二维数组矩阵运算代码示例  酷狗音乐多音轨设置教程  React应用中Commerce.js数据加载与状态管理最佳实践  搜狗浏览器如何查找页面中的文字 搜狗浏览器Ctrl+F页面搜索功能  sublime如何撤销关闭的标签页_sublime重新打开已关闭文件技巧  J*aScript与HTML元素交互:图片点击事件与链接处理教程  Sublime怎么快速复制文件路径_Sublime右键菜单增强技巧  驱动人生:游戏修复指南  毒蘑菇VOLUMESHADER_BM官网首页登录入口 毒蘑菇VOLUMESHADER_BM官网首页登录入口说明  苹果电脑如何快速截图并编辑 苹果电脑截屏标注快捷操作  悟空浏览器网页版链接 悟空浏览器网页版最新有效地址  Leaflet地图弹出窗口图片动态显示:避免缺失图标的专业指南  我的世界游戏平台入口 我的世界官方官网直达链接  yy漫画官方网站登录入口_yy漫画在线阅读页面地址  win11如何运行chkdsk命令 Win11检查和修复磁盘逻辑错误教程【修复】  J*aScript桌面应用_Electron多进程架构实战  4399造梦西游3无敌版_4399游戏入口  六级准考证号怎么查_四六级准考证查询入口官网  《鹿路通》退余额方法  byrutor直接访问入口 byrutor官方游戏库  《edge浏览器》关闭翻译功能方法  《咸鱼之王》新版孙坚技能解析 

     2025-10-25

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

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

    点击免费数据支持

    提交您的需求,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.