有关此问题和问题的随附示例,请参阅this codepen。相关元数据:
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>
元素)或包含在Deleting
元素内的文本<span>
。您可以看到handleRowClick
被调用(此 问题)。有一个原因我在示例中使填充如此巨大,因为如果您在<span>
元素的边框外单击,但仍然在<button>
的边界内,则没有任何反应(其中最终是期望的效果,因为它被禁用了。)
因此浏览器之间显然不一致,这对开发人员来说很烦人。 Firefox似乎尊重开发人员的隐含假设。这会是Chrome问题吗?或者也许是React中的错误?在任何情况下,我们的客户都不能等到任何一个人解决这个问题,因此需要一个有效的解决方案,同时仍然尊重客户的愿望。有没有其他人以前遇到过这个问题,如果有,那么最好的解决方案是什么?
我能想到的唯一解决方案是我不愿意应用的解决方案:
检查event.target
回调中的handleRowClick
。然而,这增加了潜在的可维护性问题如果其中一个列具有嵌套元素,则需要添加其他逻辑以检查所点击的内容。
答案 0 :(得分:3)