0

0

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

DDD

DDD

发布时间:2025-10-25 10:40:27

|

693人浏览过

|

来源于php中文网

原创

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

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

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

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

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

    , ,
  • 等)时,React会将其转换为真实的DOM元素。这些原生HTML元素只识别标准的HTML属性。如果您尝试直接附加非标准的自定义属性,例如在以下代码片段中尝试的airport、lat、name和long:
  • {airport.name}
  • 这些非标准属性并不会被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属性中,从而允许JavaScript安全地访问它们。

    1. 附加数据属性

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

  • {airport.name}
  • 注意事项:

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

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

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

    沁言学术
    沁言学术

    你的论文写作AI助理,永久免费文献管理工具,认准沁言学术

    下载

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

    const handleLiClickFirst = (event) => {
        // event.target 指向触发事件的 
  • 元素 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 (
        
    setFirst(e.target.value.toLocaleLowerCase())} />
      {resultFirst.airports?.map((airport) => { return (
    • {airport.name}
    • ); })}
    ); } export default AirportSelector;

    最佳实践与替代方案

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

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

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

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

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

    总结

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

  • 相关专题

    更多
    js获取数组长度的方法
    js获取数组长度的方法

    在js中,可以利用array对象的length属性来获取数组长度,该属性可设置或返回数组中元素的数目,只需要使用“array.length”语句即可返回表示数组对象的元素个数的数值,也就是长度值。php中文网还提供JavaScript数组的相关下载、相关课程等内容,供大家免费下载使用。

    556

    2023.06.20

    js刷新当前页面
    js刷新当前页面

    js刷新当前页面的方法:1、reload方法,该方法强迫浏览器刷新当前页面,语法为“location.reload([bForceGet]) ”;2、replace方法,该方法通过指定URL替换当前缓存在历史里(客户端)的项目,因此当使用replace方法之后,不能通过“前进”和“后退”来访问已经被替换的URL,语法为“location.replace(URL) ”。php中文网为大家带来了js刷新当前页面的相关知识、以及相关文章等内容

    374

    2023.07.04

    js四舍五入
    js四舍五入

    js四舍五入的方法:1、tofixed方法,可把 Number 四舍五入为指定小数位数的数字;2、round() 方法,可把一个数字舍入为最接近的整数。php中文网为大家带来了js四舍五入的相关知识、以及相关文章等内容

    732

    2023.07.04

    js删除节点的方法
    js删除节点的方法

    js删除节点的方法有:1、removeChild()方法,用于从父节点中移除指定的子节点,它需要两个参数,第一个参数是要删除的子节点,第二个参数是父节点;2、parentNode.removeChild()方法,可以直接通过父节点调用来删除子节点;3、remove()方法,可以直接删除节点,而无需指定父节点;4、innerHTML属性,用于删除节点的内容。

    477

    2023.09.01

    JavaScript转义字符
    JavaScript转义字符

    JavaScript中的转义字符是反斜杠和引号,可以在字符串中表示特殊字符或改变字符的含义。本专题为大家提供转义字符相关的文章、下载、课程内容,供大家免费下载体验。

    414

    2023.09.04

    js生成随机数的方法
    js生成随机数的方法

    js生成随机数的方法有:1、使用random函数生成0-1之间的随机数;2、使用random函数和特定范围来生成随机整数;3、使用random函数和round函数生成0-99之间的随机整数;4、使用random函数和其他函数生成更复杂的随机数;5、使用random函数和其他函数生成范围内的随机小数;6、使用random函数和其他函数生成范围内的随机整数或小数。

    991

    2023.09.04

    如何启用JavaScript
    如何启用JavaScript

    JavaScript启用方法有内联脚本、内部脚本、外部脚本和异步加载。详细介绍:1、内联脚本是将JavaScript代码直接嵌入到HTML标签中;2、内部脚本是将JavaScript代码放置在HTML文件的`<script>`标签中;3、外部脚本是将JavaScript代码放置在一个独立的文件;4、外部脚本是将JavaScript代码放置在一个独立的文件。

    658

    2023.09.12

    Js中Symbol类详解
    Js中Symbol类详解

    javascript中的Symbol数据类型是一种基本数据类型,用于表示独一无二的值。Symbol的特点:1、独一无二,每个Symbol值都是唯一的,不会与其他任何值相等;2、不可变性,Symbol值一旦创建,就不能修改或者重新赋值;3、隐藏性,Symbol值不会被隐式转换为其他类型;4、无法枚举,Symbol值作为对象的属性名时,默认是不可枚举的。

    553

    2023.09.20

    微信聊天记录删除恢复导出教程汇总
    微信聊天记录删除恢复导出教程汇总

    本专题整合了微信聊天记录相关教程大全,阅读专题下面的文章了解更多详细内容。

    36

    2026.01.18

    热门下载

    更多
    网站特效
    /
    网站源码
    /
    网站素材
    /
    前端模板

    精品课程

    更多
    相关推荐
    /
    热门推荐
    /
    最新课程
    Sass 教程
    Sass 教程

    共14课时 | 0.8万人学习

    Bootstrap 5教程
    Bootstrap 5教程

    共46课时 | 2.9万人学习

    CSS教程
    CSS教程

    共754课时 | 20.6万人学习

    关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
    php中文网:公益在线php培训,帮助PHP学习者快速成长!
    关注服务号 技术交流群
    PHP中文网订阅号
    每天精选资源文章推送

    Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号