React 如何以 `this` 不引用 class 本身的方式调用 ES6 class 的渲染函数?
How does React call the render function of an ES6 class in a such a way that `this` does not refer to the class itself?
例如,给定 class 函数 increaseQty
increaseQty() {
this.qty++
}
和通话
render() {
return (
<div>
<button onClick={this.increaseQty}>Increase</button>
</div>
)
}
this.qty 将是未定义的,除非我在构造函数中写一行,将构造函数中 this
的上下文绑定到函数
constructor(props) {
super(props)
this.qty = 0
this.increaseQty = this.increaseQty.bind(this) // <---- like so
}
然而,如果您只是正常使用它,那么在普通的 es6 class 中情况并非如此:
https://jsfiddle.net/omrf0t20/2/
class Test {
constructor() {
this.qty = 0
}
increaseQty() {
console.log(++this.qty)
}
doStuff() {
this.increaseQty()
}
}
const t = new Test()
t.doStuff() // prints 1
React 的哪个方面使得 render
在没有 this
的上下文的情况下被调用?
这实际上不是 ES6 特定的问题(除了我们引用 class 和构造函数这一事实)。您在函数中所做的只是增加一个值。如果该值尚未初始化为某些东西(即使在 ES5 中),那么它将抛出错误。 undefined
.
不能加 1
在 ES5(实际上是 ES6)中,这将是一个问题:
var myObj = {
addOne: function() {
this.qty++;
}
}
myObj.addOne(); // Error! this.qty is undefined
而这将解决它:
var myObj = {
qty: 0,
addOne: function() {
this.qty++;
}
}
myObj.addOne(); // Good to go
你的class也是一样的情况。您不能递增尚未声明和初始化为数字值的变量。
在一个更简单的例子中:
var x;
x++;
会抛出一个错误,而这个:
var x = 0;
x++;
很好。
此处的区别在于,在您使用 React 的示例中,您将 increaseQty
作为回调传递给另一个组件,但在第二个组件中,您将在当前上下文中调用它。
您可以在此处的简化示例中看到差异
class Test {
constructor() {
this.qty = 0
}
increaseQty() {
console.log(++this.qty)
}
doStuff() {
this.increaseQty(); // no need to bind
}
listenClicks() {
// you should use bind to preserve context
document.body.addEventListener('click', this.increaseQty.bind(this));
}
}
React 指南还建议您在构造函数中绑定方法,以使代码更优化,绑定一次并始终使用相同的函数,而不是为每个 render()
调用创建一个新的绑定版本。
例如,给定 class 函数 increaseQty
increaseQty() {
this.qty++
}
和通话
render() {
return (
<div>
<button onClick={this.increaseQty}>Increase</button>
</div>
)
}
this.qty 将是未定义的,除非我在构造函数中写一行,将构造函数中 this
的上下文绑定到函数
constructor(props) {
super(props)
this.qty = 0
this.increaseQty = this.increaseQty.bind(this) // <---- like so
}
然而,如果您只是正常使用它,那么在普通的 es6 class 中情况并非如此:
https://jsfiddle.net/omrf0t20/2/
class Test {
constructor() {
this.qty = 0
}
increaseQty() {
console.log(++this.qty)
}
doStuff() {
this.increaseQty()
}
}
const t = new Test()
t.doStuff() // prints 1
React 的哪个方面使得 render
在没有 this
的上下文的情况下被调用?
这实际上不是 ES6 特定的问题(除了我们引用 class 和构造函数这一事实)。您在函数中所做的只是增加一个值。如果该值尚未初始化为某些东西(即使在 ES5 中),那么它将抛出错误。 undefined
.
在 ES5(实际上是 ES6)中,这将是一个问题:
var myObj = {
addOne: function() {
this.qty++;
}
}
myObj.addOne(); // Error! this.qty is undefined
而这将解决它:
var myObj = {
qty: 0,
addOne: function() {
this.qty++;
}
}
myObj.addOne(); // Good to go
你的class也是一样的情况。您不能递增尚未声明和初始化为数字值的变量。
在一个更简单的例子中:
var x;
x++;
会抛出一个错误,而这个:
var x = 0;
x++;
很好。
此处的区别在于,在您使用 React 的示例中,您将 increaseQty
作为回调传递给另一个组件,但在第二个组件中,您将在当前上下文中调用它。
您可以在此处的简化示例中看到差异
class Test {
constructor() {
this.qty = 0
}
increaseQty() {
console.log(++this.qty)
}
doStuff() {
this.increaseQty(); // no need to bind
}
listenClicks() {
// you should use bind to preserve context
document.body.addEventListener('click', this.increaseQty.bind(this));
}
}
React 指南还建议您在构造函数中绑定方法,以使代码更优化,绑定一次并始终使用相同的函数,而不是为每个 render()
调用创建一个新的绑定版本。