如何在React映射数组后不使用额外组件通过HTML属性传递数据?
问题解决:React中通过点击事件传递数据的正确方式
为什么你的代码无法读取属性?
你给<li>添加的自定义属性(比如lat、airport)并不是标准HTML属性,React不会将这些属性直接附加到最终的DOM元素上,所以在事件处理函数里通过airport.target.lat自然读不到值。
方案1:使用data-*自定义属性
HTML支持以data-为前缀的自定义属性,这些属性会被添加到DOM元素的dataset对象中,你可以通过event.target.dataset来访问:
修改后的代码:
const handleLiClickFirst = (e) => { setFirst(e.target.innerHTML); // 通过dataset访问自定义属性 console.log(e.target.dataset.lat); console.log(e.target.dataset.long); console.log(e.target.dataset.name); }; <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, i) => { return ( <li key={airport.iata} onClick={handleLiClickFirst} // 用data-前缀定义自定义属性 data-lat={airport.latitude} data-name={airport.name} data-long={airport.longitude} > {airport.name} </li> ); })} </ul> </div>
方案2:直接在事件绑定中传递数据(更推荐)
不需要依赖DOM属性,直接在绑定onClick时把airport对象作为参数传入事件处理函数,这种方式更符合React的数据流逻辑:
修改后的代码:
const handleLiClickFirst = (airport) => { setFirst(airport.name); console.log(airport.latitude); console.log(airport.longitude); console.log(airport.name); }; <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, i) => { return ( <li key={airport.iata} // 直接传递airport参数,用箭头函数包裹 onClick={() => handleLiClickFirst(airport)} > {airport.name} </li> ); })} </ul> </div>
注意点
- 方案2中使用箭头函数包裹事件处理函数,每次渲染都会创建新的函数实例,但对于列表项这种场景,性能影响可以忽略;如果担心性能,可以使用
useCallback来缓存事件处理函数。 - 避免直接在DOM元素上绑定复杂对象(比如方案1里如果传整个
airport对象到data属性,需要先转成JSON字符串,读取时再解析,不如方案2直接)。
内容的提问来源于stack exchange,提问作者Utku AKTAS
相关产品推荐
相关产品推荐

