我很难理解为什么create-react-app
无法编译,告诉我error 'updateWord' is not defined no-undef
。我对与ES6的React相当新。通常我会写一个像const App = React.createClass({ });
这样的组件,但我决定尝试一些语法糖。
我有父组件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>
);
}
}
我已尝试更改为this.updateWord(input);
而不是updateWord(input)
,但无济于事。我明白了:
"App.js:55 Uncaught TypeError: this.updateWord is not a function"
通常当我实现与我现在所做的类似模式(使用ES5)时,我没有遇到任何困难。例如:
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>
);
}
}
答案 0 :(得分:3)
问题是,当您this.updateWord(...)
this.handleInput
this
时,Input
会引用onInput
组件。让我来说明问题:
设置onInput={this.handleInput}
处理程序时,如下所示:
Input
此处,由于您的this
组件正在调用该函数,因此Input
引用this.props.onInput(input);
组件。这是由于行:
Input
handleInput
组件正在调用handleInput
。这意味着,在this
函数中,Input
上下文为this.updateWord(input);
。考虑一下:
handleInput
this.updateWord
函数中的。在这里,您致电this
,但由于Input
为updateWord
,它会尝试从Input
调用不存在的this
,从而引发错误。
解决方案是使用{{3}显式绑定App
上下文作为类(Input
组件)而不是bind()
组件或Function.prototype.bind
。来自文档:
this
方法创建一个新函数,在调用时,将onInput={this.handleInput.bind(this)}
关键字设置为提供的值
你可以这样申请:
this.handleInput = this.handleInput.bind(this);
或者更优选地在构造函数中:
onInput={this.handleInput}
使用第二个选项,您可以这样做:
render
(这更为可取,因为this
方法中的绑定每次渲染时都会创建一个新函数,这不是首选。)
上面一行中的this
上下文是类。由于绑定this
,类将在函数中正确用作this.updateWord
上下文,执行this
将调用类中的方法< / em>的。
更优选的方法是使用箭头功能而不是常规的ES6方法。来自文档:
箭头函数表达式与函数表达式相比具有更短的语法,并且不绑定自己的
arguments
,super
,new.target
或handleInput
。
我们可以通过将handleInput = (input) => {
console.log(`handle: ${input}`);
this.updateWord(input);
}
分配给箭头函数而不是常规方法来应用它:
bind
这将完全取消this
的使用,而是使用箭头功能。由于箭头函数不会绑定自己的this
,因此this
表示封闭的上下文。在上面的示例中,未使用方法,因此updateWord
引用类(封闭上下文)。这将正确调用类方法onInput
,因此,如果你走这条路线,你不需要改变even_strings
事件处理程序。