React JS中使用bind绑定HandleClick点击事件失效问题
React点击事件绑定失效问题排查与解决
嘿,我来帮你搞定React里点击事件绑定失效的问题!先把你给出的代码格式化出来,方便分析:
事件处理函数代码
// 箭头函数定义的处理函数 handleRemoveClick = material => { let idMaterial = material.material_id; if(this.state.operation === 0){ this.setState( { previewShowAlertRemoveProduct : true }) } this.setState( { operation : 1, material_id : idMaterial}) } // 普通函数定义的处理函数 handleEndOrder(){ if(this.state.operation === 0){ this.setState( { previewShowAlertRemoveProduct : true }) } this.setState( { operation : 2}) }
视图渲染代码片段
<button class="btn btn-xs btn-danger pull-right" onClick={e => this...}>
问题分析与解决方案
从代码来看,handleRemoveClick用箭头函数类属性定义,这种写法会自动把this绑定到组件实例,理论上不会出现this丢失导致的事件失效;但handleEndOrder是普通函数,如果绑定方式不对,就会因为this指向错误导致事件失效。下面给你几种靠谱的解决方式:
1. 用箭头函数包裹调用(最简便)
在onClick里用箭头函数直接调用处理函数,这种方式能确保this指向组件实例,还能方便传参:
// 调用handleRemoveClick(带参数) <button className="btn btn-xs btn-danger pull-right" onClick={(e) => this.handleRemoveClick(material)}> 移除物料 </button> // 调用handleEndOrder(无参数) <button className="btn btn-xs btn-danger pull-right" onClick={() => this.handleEndOrder()}> 结束订单 </button>
注意:React里元素的类名要用
className替代class,不然样式可能不生效哦!
2. 在构造函数中提前bind(传统写法)
如果你的组件是类组件,可以在constructor里提前把普通函数的this绑定好,之后直接在onClick里引用函数即可:
constructor(props) { super(props); // 绑定this到组件实例 this.handleEndOrder = this.handleEndOrder.bind(this); }
然后视图里这样写:
<button className="btn btn-xs btn-danger pull-right" onClick={this.handleEndOrder}> 结束订单 </button>
3. 把普通函数改成箭头函数类属性
和handleRemoveClick一样,把handleEndOrder改成箭头函数类属性,自动绑定this,不用额外处理:
handleEndOrder = () => { if(this.state.operation === 0){ this.setState( { previewShowAlertRemoveProduct : true }) } this.setState( { operation : 2}) }
之后直接在onClick里使用:
<button className="btn btn-xs btn-danger pull-right" onClick={this.handleEndOrder}> 结束订单 </button>
额外优化建议
你在两个处理函数里都连续调用了两次setState,因为setState是异步操作,建议合并成一次调用,这样更高效:
// 优化后的handleRemoveClick handleRemoveClick = material => { let idMaterial = material.material_id; const updateState = { operation: 1, material_id: idMaterial }; if(this.state.operation === 0){ updateState.previewShowAlertRemoveProduct = true; } this.setState(updateState); } // 优化后的handleEndOrder handleEndOrder = () => { const updateState = { operation: 2 }; if(this.state.operation === 0){ updateState.previewShowAlertRemoveProduct = true; } this.setState(updateState); }
内容的提问来源于stack exchange,提问作者user9655816
相关产品推荐
相关产品推荐

