本文探讨了在React应用中,如何正确地将自定义数据附加到原生HTML元素(如`
在React中,当我们将组件渲染为原生HTML元素(例如div, ul, li等)时,我们必须遵守HTML规范。直接向这些原生元素添加非标准属性,如示例中尝试的airport={airport}、lat={airport.latitude}或name={airport.name},是无效的。浏览器会忽略这些非标准属性,或者即使在DOM中可见,也无法通过标准DOM API(如event.target.property)可靠地访问它们。因此,在事件处理函数中,尝试通过airport.target.lat等方式获取数据会失败,因为这些属性并未被正确地附加到DOM元素上。
为了在原生HTML元素上存储自定义数据,并能在JavaScript事件处理函数中访问它们,HTML5引入了data属性。data属性以data-前缀开头,后跟自定义的名称,例如data-latitude、data-airport-id等。这些属性的值可以是任何字符串。
当一个元素具有data属性时,可以通过JavaScript中的HTMLElement.dataset属性来访问它们。dataset是一个DOMStringMap对象,其中包含了所有data-属性的键值对,键名是data-后面的部分(自动转换为驼峰命名法)。
让我们根据原有的问题,修改代码以使用data属性来传递机场信息。
import React, { useState } from 'react';
import { TextField } from '@mui/material'; // 假设你正在使用MUI的TextField
function AirportSelector({ airportsData }) { // 假设airportsData是传入的机场列表
const [first, setFirst] = useState('');
const [resultFirst, setResultFirst] = useState({ airports: airportsData }); // 假设数据源
const handleLiClickFirst = (event) => {
// 通过 event.target.dataset 访问 data 属性
const selectedLatitude = event.target.dataset.latitude;
const selectedLongitude = event.target.dataset.longitude;
const selectedName = event.target.dataset.name;
const selectedIata = event.target.dataset.iata;
// 如果需要完整的机场对象,可以从 data-airport 属性中解析
// 注意:如果 airport 对象很大,不建议直接存储整个对象
const airportDataString = event.target.dataset.airport;
const fullAirportObject = airportDataString ? JSON.parse(airportDataString) : null;
setFirst(selectedName); // 更新输入框显示名称
console.log('Selected Name:', selectedName);
console.log('Selected Latitude:', selectedLatitude);
console.log('Selected Longitude:', selectedLongitude);
console.log('Selected IATA:', selectedIata);
if (fullAirportObject) {
console.log('Full Airport Object:', fullAirportObject);
}
};
return (
setFirst(e.target.value.toLocaleLowerCase())}
/>
{resultFirst.airports?.map((airport) => (
-
{airport.name}
))}
);
}
export default AirportSelector; data-airport={JSON.stringify(airport)}const fullAirportObject = JSON.parse(event.target.dataset.airport);
然后在处理函数中:
const selectedIata = event.target.dataset.iata; const fullAirportObject = resultFirst.airports.find(a => a.iata === selectedIata);
在React中,当需要将自定义数据附加到原生HTML元素上,并在事件处理函数中访问这些数据时,HTML5的data属性是标准且推荐的解决方案。通过data-attribute-name语法设置属性,并通过event.target.dataset.attributeName在JavaScript中获取数据,可以有效避免直接使用非标准属性带来的问
题。同时,合理规划所存储的数据量和类型,尤其是在处理复杂对象时,以保持代码的性能和可维护性。