You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.12 02:24:51