React商品按钮点击异常:仅首次点击生效,后续点击无响应
问题
在React项目中实现商品下单按钮功能时遇到异常:点击第一个按钮能正常在右侧显示下单内容,但点击第二个按钮无响应;刷新页面后点击第二个按钮能显示,再点第一个也没反应。相关代码如下:
app.js 代码片段
<button onClick={(price) => test("samosa")} class="button-56" id="order" > Order Samosa </button> <div class="price">Price: ₹15</div> <div class="aval"> Availability:<span id="span">Yes</span> </div> </div> <div class="items"> <img src={im2} alt="" class="image" /> <button onClick={(price) => test("veg puff")} class="button-56" id="order" > Order Veg Puff </button> <div class="price">Price: ₹25</div> <div class="aval"> Availability:<span id="span">Yes</span> </div> </div>
cart.js 代码
export function test(value) { return ( (document.getElementById("body").innerHTML += `<div class='right'>order ${value}</div>`) ); }
问题原因
- 重复ID违反HTML规则:两个按钮都用了
id="order",两个可用性提示的span都用了id="span",HTML要求ID必须唯一,重复ID会导致DOM元素识别混乱,后续按钮的事件绑定可能失效。 - 原生DOM操作破坏React机制:
document.getElementById("body").innerHTML += ...这种直接修改真实DOM的方式,会打乱React虚拟DOM和真实DOM的同步关系,第一次修改后,React管理的组件事件绑定被销毁,导致后续按钮点击无响应。
解决方案
1. 修正ID与JSX语法问题
把重复ID去掉或改成唯一值,同时React的JSX语法中要把class替换为className:
<button onClick={() => addToCart("samosa")} className="button-56" > Order Samosa </button> <div className="price">Price: ₹15</div> <div className="aval"> Availability:<span>Yes</span> </div> </div> <div className="items"> <img src={im2} alt="Veg Puff" className="image" /> <button onClick={() => addToCart("veg puff")} className="button-56" > Order Veg Puff </button> <div className="price">Price: ₹25</div> <div className="aval"> Availability:<span>Yes</span> </div> </div>
2. 用React状态管理购物车(替代原生DOM操作)
React的核心是状态驱动UI,通过useState维护购物车列表,让UI自动跟随状态变化:
import { useState } from 'react'; function App() { // 用状态存储购物车商品 const [cartItems, setCartItems] = useState([]); // 添加商品到购物车的方法 const addToCart = (item) => { setCartItems(prevItems => [...prevItems, item]); }; return ( <> {/* 前面的商品展示代码 */} <div className="items"> {/* 第一个商品按钮 */} <button onClick={() => addToCart("samosa")} className="button-56" > Order Samosa </button> {/* 第二个商品按钮 */} <button onClick={() => addToCart("veg puff")} className="button-56" > Order Veg Puff </button> {/* 其他商品信息 */} </div> {/* 购物车展示区域 */} <div className="cart-container"> {cartItems.map((item, index) => ( <div key={index} className="right">order {item}</div> ))} </div> </> ); } export default App;
3. 移除原生DOM操作的代码
原来cart.js中的test函数可以直接删除,改用上述React状态管理的方式,完全符合React的开发规范。
内容的提问来源于stack exchange,提问作者Le Van dees
相关产品推荐
相关产品推荐

