[英]ES6 method is not defined in create-react-app
I'm having difficulty understanding why create-react-app
is unable to compile, telling me that error 'updateWord' is not defined no-undef
.我很难理解为什么create-react-app
无法编译,告诉我error 'updateWord' is not defined no-undef
。 I'm fairly new to React with ES6.我对使用 ES6 进行 React 相当陌生。 Normally I would write a component like const App = React.createClass({ });
通常我会写一个像const App = React.createClass({ });
这样的组件const App = React.createClass({ });
but I've decided to try out some syntactical sugar instead.但我决定尝试一些语法糖。
I have parent component App
and a child component Input
:我有父组件App
和子组件Input
:
class App extends Component {
constructor(props) {
super(props);
// all other code omitted...
}
handleInput(input) {
console.log(`handle: ${input}`);
updateWord(input);
// this also causes an error
// this.updateWord(input);
}
updateWord(input) {
console.log(`update ${input}`);
// why isn't this defined?
}
render() {
return (
<div className="App">
<Input onInput={this.handleInput} />
</div>
);
}
}
class Input extends Component {
handleInput(e) {
let input = e.target.value;
this.props.onInput(input);
}
render() {
return (
<form>
<input onChange={this.handleInput.bind(this)} />
</form>
);
}
}
I've tried changing to this.updateWord(input);
我试过this.updateWord(input);
instead of updateWord(input)
but to no avail.而不是updateWord(input)
但无济于事。 I get:我得到:
"App.js:55 Uncaught TypeError: this.updateWord is not a function"
Normally when I implement a similar pattern (with ES5) to what I'm doing now I have no difficulties.通常,当我实现与我现在所做的类似的模式(使用 ES5)时,我没有任何困难。 For example:例如:
const App = React.createClass({
getInitialState: function() {
// all other code omitted...
},
handleInput: function(input) {
console.log(`handle: ${input}`);
this.updateWord(input);
},
updateWord: function(input) {
console.log(`update ${input}`);
// In theory, this implementation would not cause any errors?
},
render: function() {
return (
<div className="App">
<Input onInput={this.handleInput} />
</div>
);
}
}
The problem is that when you do this.updateWord(...)
in this.handleInput
, this
refers to the Input
component.问题是,当你做this.updateWord(...)
在this.handleInput
, this
指的是Input
组件。 Let me illustrate the problem:让我来说明这个问题:
When you set the onInput
handler, like so:当您设置onInput
处理程序时,如下所示:
onInput={this.handleInput}
Here, since your Input
component is calling the function, this
refers to the Input
component.在这里,由于您的Input
组件正在调用该函数, this
指的是Input
组件。 This is due to the line:这是由于以下行:
this.props.onInput(input);
The Input
component is calling handleInput
. Input
组件正在调用handleInput
。 That means, in your handleInput
function, the this
context is Input
.这意味着,在您的handleInput
函数中, this
上下文是Input
。 Consider the line:考虑这一行:
this.updateWord(input);
in the handleInput
function.在handleInput
函数中。 Here you call this.updateWord
, but since this
is Input
, it tries to call updateWord
from Input
which does not exist, thus throwing the error.在这里您调用this.updateWord
,但由于this
是Input
,它尝试从不存在的Input
调用updateWord
,从而updateWord
错误。
The solution is to explicitly bind the this
context as the class ( App
component) instead of the Input
component, using either Function.prototype.bind
or an arrow function .解决方案是使用Function.prototype.bind
或箭头函数将this
上下文显式绑定为类( App
组件)而不是Input
组件。 From the documentation:从文档:
The
bind()
method creates a new function that, when called, has itsthis
keyword set to the provided valuebind()
方法创建一个新函数,当调用this
函数时,将其this
关键字设置为提供的值
You can apply it like so:您可以像这样应用它:
onInput={this.handleInput.bind(this)}
Or more preferably in the constructor:或者更优选地在构造函数中:
this.handleInput = this.handleInput.bind(this);
With the second option you may then do:使用第二个选项,您可以执行以下操作:
onInput={this.handleInput}
(This is more preferable as binding in the render
method will create a new function every time on render, which isn't preferred). (这更可取,因为render
方法中的绑定将在每次render
时创建一个新函数,这不是首选)。
The this
context in the line above is the class.上一行中的this
上下文是类。 Since you bind this
, the class will be correctly used as this
context in the function and executing this.updateWord
will invoke the method in the class .由于您绑定了this
,该类将被正确用作函数中的this
上下文,并且执行this.updateWord
将调用该类中的方法。
An even more preferable way is to use arrow functions instead of regular ES6 methods.更可取的方法是使用箭头函数而不是常规的 ES6 方法。 From the documentation:从文档:
An arrow function expression has a shorter syntax compared to function expressions and does not bind its own
this
,arguments
,super
, ornew.target
.与函数表达式相比,箭头函数表达式的语法更短,并且不绑定自己的this
、arguments
、super
或new.target
。
We can apply this by assigning handleInput
to an arrow function instead of a regular method:我们可以通过将handleInput
分配给箭头函数而不是常规方法来应用它:
handleInput = (input) => {
console.log(`handle: ${input}`);
this.updateWord(input);
}
This will eliminate the use of bind
completely and instead, use arrow functions.这将完全消除bind
的使用,而是使用箭头函数。 Since arrow functions don't bind their own this
, it means this
refers to the enclosing context.由于箭头函数不绑定自己的this
,这意味着this
指的是封闭的上下文。 In the example above, a method is not used thus this
refers to the class (the enclosing context).在上面的例子中,没有使用方法,因此this
指的是类(封闭上下文)。 That will correctly call the class method updateWord
, and consequently, you need not change the onInput
event handler if you go this route.这将正确调用类方法updateWord
,因此,如果您走这条路线,则无需更改onInput
事件处理程序。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.