[英]React stopPropagation onClick for disabled button with nested elements
有关与此问题和问题相关的示例,请参见此代码笔 。 相关元数据:
react 15.6
bootstrap 4.0-beta
font-awesome 4.7
v55.0
v60.0
我有一张桌子,里面有一些数据。 用户可以单击一行并编辑该行的属性。 在每一行的一列中,有一个按钮。 单击该按钮时,将执行其他操作和用例。 此操作是异步的,用户会收到有关此异步操作的反馈。
单击按钮与单击按钮边界之外(因此单击“ 行 ”)不同。
class App extends React.Component {
constructor(props){
super(props);
this.state = {
isDeleting: false
};
this.handleRowClick = this.handleRowClick.bind(this);
this.handleButtonClick = this.handleButtonClick.bind(this);
}
handleRowClick(event) {
alert("you clicked the row [use case 1]");
}
handleButtonClick(event){
event.stopPropagation();
this.setState({isDeleting: true});
alert("you clicked the button [use case 2]");
}
render() {
return (
<table className="table">
<thead>
<tr>
<th>Header 1</th>
<th>Header 2</th>
<th></th>
</tr>
</thead>
<tbody>
<tr onClick={this.handleRowClick}>
<td>Data 1</td>
<td>Data 2</td>
<td>
<button disabled={this.state.isDeleting}
className="btn btn-outline-danger btn-sm p-5"
type="button"
onClick={this.handleButtonClick}>
{
this.state.isDeleting
? <span><i className="fa fa-spinner fa-pulse"/> Deleting</span>
: "Delete"
}
</button>
</td>
</tr>
</tbody>
</table>
);
}
}
在上面的代码示例中,您可以看到,只要单击该按钮,该按钮就会被禁用( 实际上,在异步操作完成之前 ,该按钮一直处于禁用状态 )。 在示例中,该按钮被永久禁用以证明这一点。
当您使用Firefox
在Codepen中进行尝试时,UI的行为符合预期。 如果在禁用按钮的情况下尝试单击按钮,则不会发生任何事情:这是所需的效果。
但是,当您使用Chrome
尝试此操作时,会发生不良效果。 首先单击该按钮,然后在禁用该按钮时,单击加载图标( <i>
元素)或包装在<span>
元素内的文本“ Deleting
。 您可以看到handleRowClick
被调用了(这就是问题)。 有一个原因使示例中的填充变得如此之大,因为如果您在<span>
元素的边界之外单击,但仍在<button>
的边界之内<button>
,则什么都不会发生(这最终是所希望的)效果,因为它已被禁用)。
因此,这显然在浏览器之间是不一致的,这对于开发人员来说很烦人。 Firefox似乎尊重开发人员的隐含假设。 那么这会是Chrome问题吗? 还是React中的错误? 在任何情况下,我们的客户都不能等到任何一个解决此问题后,就需要一个可行的解决方案,同时还要尊重客户的意愿。 之前是否有人遇到过此问题?如果可以,最好的解决方案是什么?
我能想到的唯一解决方案是我不愿采用的解决方案:
检查handleRowClick
回调中的event.target
。 但是,这引起了潜在的可维护性问题。 如果该列的其中之一具有嵌套元素,则需要添加其他逻辑以检查所单击的内容。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.