React中如何直接调用action处理动态创建的删除按钮事件?
解决方案
一、修复当前DOM操作的写法
你之前用setAttribute绑定点击事件的方式会导致this指向错误,且字符串形式的函数调用存在作用域问题。直接改用addEventListener绑定事件,通过箭头函数保留组件实例的this指向即可解决:
修改你的newRoomClicked方法:
@action newRoomClicked = async (event, meta) => { // do something const removeRoomBtn = document.createElement('button'); removeRoomBtn.type = 'button'; removeRoomBtn.textContent = 'Remove'; // 用addEventListener绑定点击事件,箭头函数确保this指向组件实例 removeRoomBtn.addEventListener('click', () => { // 删除对应的DOM元素 document.getElementById(newDivRoomId).remove(); // 直接调用组件的action方法 this.removeRoomUpdateRunningFee(); }); Div.appendChild(removeRoomBtn); }
如果需要把newDivRoomId传入removeRoomUpdateRunningFee,可先修改该方法:
@action removeRoomUpdateRunningFee = (roomId) => { this.numberOfNewRooms = parseInt(this.numberOfNewRooms) - 1; this.handleRunningFeeChangeRoom(); }
再绑定事件时直接传参:
removeRoomBtn.addEventListener('click', () => { document.getElementById(newDivRoomId).remove(); this.removeRoomUpdateRunningFee(newDivRoomId); });
为什么之前的写法失效?
- 用
setAttribute('onClick', 'this.removeRoomUpdateRunningFee')时,字符串里的this指向按钮元素本身,而非React组件实例,因此找不到组件的removeRoomUpdateRunningFee方法。 - 写成
'this.removeRoomUpdateRunningFee()'时,代码会在设置属性的瞬间立即执行,而非点击按钮时触发,同时仍存在this指向错误的问题。
二、更符合React范式的优化方案
直接操作DOM不符合React「数据驱动视图」的核心理念,推荐用状态管理房间列表,完全抛弃原生DOM操作:
class YourComponent extends Component { constructor(props) { super(props); // 用数组状态管理所有房间 this.state = { rooms: [] }; } @action newRoomClicked = async (event, meta) => { // 生成唯一房间ID,可根据实际需求调整 const newRoomId = `room-${Date.now()}`; // 更新状态添加新房间 this.setState(prevState => ({ rooms: [...prevState.rooms, { id: newRoomId }] })); }; @action removeRoomUpdateRunningFee = (roomId) => { // 从状态中移除对应房间 this.setState(prevState => ({ rooms: prevState.rooms.filter(room => room.id !== roomId) })); // 更新房间数量并计算费用 this.numberOfNewRooms = this.state.rooms.length - 1; this.handleRunningFeeChangeRoom(); }; render() { return ( <div> {/* 添加房间按钮 */} <button onClick={this.newRoomClicked}>添加新房间</button> {/* 渲染所有房间 */} {this.state.rooms.map(room => ( <div key={room.id} id={room.id}> {/* 这里放房间的内容 */} <button onClick={() => this.removeRoomUpdateRunningFee(room.id)}>Remove</button> </div> ))} </div> ); } }
这种方式通过状态控制视图渲染,代码更简洁易维护,也避免了原生DOM操作带来的各种潜在问题。
内容的提问来源于stack exchange,提问作者John
相关产品推荐
相关产品推荐

