我得到以下错误
未捕获的TypeError:无法读取未定义的属性“set state”
即使在构造函数中绑定delta之后也是如此。
class Counter extends React.Component {
constructor(props) {
super(props);
this.state = {
count : 1
};
this.delta.bind(this);
}
delta() {
this.setState({
count : this.state.count++
});
}
render() {
return (
<div>
<h1>{this.state.count}</h1>
<button onClick={this.delta}>+</button>
</div>
);
}
}
这是因为This.delta
没有绑定到This
。
为了绑定,在构造函数中设置this.delta=this.delta.bind(this)
:
constructor(props) {
super(props);
this.state = {
count : 1
};
this.delta = this.delta.bind(this);
}
当前,您正在调用BIND。但bind返回一个绑定函数。您需要将函数设置为其绑定值。
在ES7+(ES2016)中,您可以使用实验性函数bind语法操作符::
进行绑定。这是一个句法糖,将做同样的戴文特雷翁的答案。
然后可以将this.delta.bind(this);
重写为this.delta=::this.delta;
对于ES6+(ES2015),您还可以使用ES6+箭头函数(=>
)来使用this
。
delta = () => {
this.setState({
count : this.state.count + 1
});
}
为什么?来自Mozilla文档:
在arrow函数之前,每个新函数都定义了自己的这个值[...]。对于面向对象的编程风格,这被证明是令人讨厌的。
箭头函数捕获封闭上下文[...]的此值
ES5和ES6班级的语境存在差异。因此,这两个实现之间也会有一些差异。
下面是ES5版本:
var Counter = React.createClass({
getInitialState: function() { return { count : 1 }; },
delta: function() {
this.setState({
count : this.state.count++
});
},
render: function() {
return (
<div>
<h1>{this.state.count}</h1>
<button onClick={this.delta}>+</button>
</div>
);
}
});
下面是ES6版本:
class Counter extends React.Component {
constructor(props) {
super(props);
this.state = { count : 1 };
}
delta() {
this.setState({
count : this.state.count++
});
}
render() {
return (
<div>
<h1>{this.state.count}</h1>
<button onClick={this.delta.bind(this)}>+</button>
</div>
);
}
}
只是要小心,除了类实现中的语法差异之外,事件处理程序绑定也有差异。
在ES5版本中,它是
<button onClick={this.delta}>+</button>
在ES6版本中,它是:
<button onClick={this.delta.bind(this)}>+</button>