小小bug
最近在写Reactjs,今天在写项目代码的过程中遇到了一个bug,记录一下.
由于项目的css修改,就去修改其中的一个React Component.然后奇怪的事情发生了,component里的Render方法被执行了两次。
代码如下
修改前
var Demo = React.createClass({
displayName: 'Demo',
getInitialState: function () {
return {
values: []
};
},
handleAdd: function () {
var values = this.state.values;
values.push('');
this.setState({
values: values
});
},
handleReduce: function (i, e) {
this.setState({
values: this.state.values.filter(function (v, _i) {
return i !== _i;
})
});
},
handleOnBlur: function (i, e) {
this.setState({
values: this.state.values.map(function (v, _i) {
return i === _i ? e.target.value : v;
})
});
},
render: function () {
return React.createElement('div', null,
React.createElement('button', {
onClick: this.handleAdd
}, '+'),
this.state.values.map(function (v, i) {
return React.createElement('div', null,
React.createElement('button', {
onClick: this.handleReduce(this, i)
}, '-'),
React.createElement('input', {
defaultValue: v,
onBlur: this.handleOnBlur.bind(this, i)
})
);
}, this)
);
}
});
修改后
var Demo = React.createClass({
displayName: 'Demo',
getInitialState: function () {
return {
values: []
};
},
handleAdd: function (e) {
e.preventDefault();
var values = this.state.values;
values.push('');
this.setState({
values: values
});
},
handleReduce: function (i, e) {
e.preventDefault();
this.setState({
values: this.state.values.filter(function (v, _i) {
return i !== _i;
})
});
},
handleOnBlur: function (i, e) {
this.setState({
values: this.state.values.map(function (v, _i) {
return i === _i ? e.target.value : v;
})
});
},
render: function () {
return React.createElement('div', null,
React.createElement('button', {
onClick: this.handleAdd
}, '+'),
this.state.values.map(function (v, i) {
return React.createElement('div', null,
React.createElement('button', {
onClick: this.handleReduce(this, i)
}, '-'),
React.createElement('input', {
defaultValue: v,
onBlur: this.handleOnBlur.bind(this, i)
})
);
}, this)
);
}
});
我只是将 div
改成了 label
,引起了一个bug,render里的方法被调用了两次。最后调试很久才发现问题出在label
这个标签。
HTML里label
focus 的话里面的元素也会focus,造成了事件冒泡。当我点击 -
的时候 -
button 的事件执行结束以后,传递给 +
,结果导致我删除一个输入框以后又回多出一个空白的输入框。 导致一个非常奇怪的bug。
最后的解决办法是在 -
事件执行的最开始添加 e.preventDefault()
函数阻止事件继续传递下去。
这让我想到了之前看到的一句话,在任何事件的执行前都要执行 preventDefault 函数。