我正在阅读一个React教程,并且讲师正在显示此代码中的事件处理程序将不起作用,因为this()正在访问外部环境。但是我没有错。有人可以向我解释吗?
import React, { Component } from "react";
class Counter extends Component {
state = {
count: 0,
};
handleIncrement() {
console.log(this.state);
console.log(this.props);
}
render() {
return (
<div>
<button onClick={this.handleIncrement()}>
Increment
</button>
</div>
);
}
}
export default Counter;
答案 0 :(得分:1)
问题是,当您的事件处理程序需要从本地范围访问this
时,您调用了这样的方法; this.handleClick()
,您要告诉JavaScript实现方法的任务,即立即到达该方法(在您的情况下,立即将其呈现),通常不需要绑定到this
。
但是当您“调用”(我将其引号,因为正确的单词应为REFER)时,是这样的方法; this.handleClick
,您实际上是在指该方法(意味着仅当用户执行某些操作时才应调用该方法),而不是立即调用它。这需要绑定this.handleClick= this.handleClick.bind(this);
或对方法handleClick = () => {};
使用箭头功能。它主要用于onClick
功能。
您没有在代码中得到该错误,因为您包括了括号-this.handleIncrement()
。如果您删除括号并在consoleLog
中仍this.state
handleIncrement
,肯定会出现undefined
错误。但是,如果您的handleIncrement
仅记录了状态以外的内容,则不会收到错误消息。
如果您了解我的基本解释,请接受答案。
答案 1 :(得分:0)
从render方法直接调用 的任何函数都将获取容器对象为this
但是,当我们将函数分配给onClick
事件时,我们不想立即调用该函数...所以我们这样分配它
<button onClick={this.handleIncrement}>
(仅末尾没有()
的函数名)...这表示单击按钮时调用该函数。
但是,当您单击按钮时,将不再从render
方法中调用该函数,因此this
引用将被更改并产生错误。
在您的情况下,您将()
添加到了this.handleIncrement
函数中,因此立即调用了它……因此它不会引起任何问题,但是在几乎所有情况下,由于它不会给您带来错误的结果,不会在click
上被调用,但是它将在每次渲染时被调用。
由于您的简单代码仅在单击按钮时呈现,因此可能可以解决问题。 添加第二个按钮,它将给出错误的结果,或者UI冻结。
正确的方法是删除()
之后的this.handleIncreament
并将函数绑定到构造函数 ... this.handleIncreament = this.handleIncreament.bind(this)
答案 2 :(得分:0)
正如Afzal Hossain所说,您是在渲染元素时而不是单击按钮时调用this.handleIncrement()
。
您需要向onClick
提供函数句柄,并在构造函数时将其bind()
置于正确的上下文中,以便this
始终访问{{1}的实例}在Counter
中。
以下是他在回答中提出的建议的有效实施方式:
handleIncrement()
const { Component } = React;
class Counter extends Component {
state = { count: 0 };
handleIncrement = this.handleIncrement.bind(this);
handleIncrement () {
const { count } = this.state;
this.setState({ count: count + 1 });
}
render () {
return <label>
<div>Count {this.state.count}</div>
<button onClick={this.handleIncrement}>Increment</button>
</label>;
}
}
ReactDOM.render(<Counter/>, document.querySelector('main'));
答案 3 :(得分:0)
如果没有bind()方法,则可以在handleincrement中直接使用箭头功能。 检查以下代码
const { Component } = React;
class Counter extends Component {
state = { count: 0 };
handleIncrement=()=> {
const { count } = this.state;
this.setState({ count: count + 1 });
}
render () {
return <label>
<div>Count {this.state.count}</div>
<button onClick={this.handleIncrement}>Increment</button>
</label>;
}
}
ReactDOM.render(<Counter/>, document.querySelector('main'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
<main/>
答案 4 :(得分:0)
我同意Afzal Hossain。
<button onClick={this.handleIncrement()}>
此行将在渲染时调用 handleIncrement
函数。这不是添加事件的正确方法。
<button onClick={this.handleIncrement}>
这将是调用函数的正确方法。但由于它是一个回调,它不会知道 this
是什么,因为它不在同一个上下文中。
React Documentation 非常清楚为什么我们应该始终将回调函数与 this
绑定以使上下文在该特定函数中可用。
但是,如果你不想绑定你的函数,react 文档中提到了两种解决方法
公共类字段语法
import React, { Component } from "react";
class Counter extends Component {
state = {
count: 0,
};
handleIncrement = () => {
console.log(this.state);
console.log(this.props);
}
render() {
return (
<div>
<button onClick={this.handleIncrement}>
Increment
</button>
</div>
);
}
}
export default Counter;
ReactDOM.render(<Counter/>, document.querySelector('main'));
箭头函数
import React, { Component } from "react";
class Counter extends Component {
state = {
count: 0,
};
handleIncrement() {
console.log(this.state);
console.log(this.props);
}
render() {
return (
<div>
<button onClick={() => this.handleIncrement()}>
Increment
</button>
</div>
);
}
}
export default Counter;
有关详细信息,请参阅此 documentation 链接。