我正在ES6中编写一个简单的组件(使用BabelJS),并函数此。setState不工作。
典型的错误包括
无法读取undefined的属性“setState”
or
这一点。setState不是一个函数
你知道为什么吗?代码如下:
import React from 'react'
class SomeClass extends React.Component {
constructor(props) {
super(props)
this.state = {inputContent: 'startValue'}
}
sendContent(e) {
console.log('sending input content '+React.findDOMNode(React.refs.someref).value)
}
changeContent(e) {
this.setState({inputContent: e.target.value})
}
render() {
return (
<div>
<h4>The input form is here:</h4>
Title:
<input type="text" ref="someref" value={this.inputContent}
onChange={this.changeContent} />
<button onClick={this.sendContent}>Submit</button>
</div>
)
}
}
export default SomeClass
Alexandre Kirszenberg是对的,但另一件需要注意的重要事情是你把你的装订在哪里。我已经被这种情况困了好几天了(可能是因为我是初学者),但不像其他人,我知道bind(我已经应用了),所以我只是不明白为什么我仍然有这些错误。原来我把绑定的顺序弄错了。
另一个原因可能是我在this中调用了函数。State”,它不知道绑定,因为它恰好在绑定线之上,
以下是我的想法(顺便说一下,这是我第一次发帖,但我认为这很重要,因为我在其他地方找不到解决方案):
constructor(props){
super(props);
productArray=//some array
this.state={
// Create an Array which will hold components to be displayed
proListing:productArray.map(product=>{return(<ProRow dele={this.this.popRow()} prodName={product.name} prodPrice={product.price}/>)})
}
this.popRow=this.popRow.bind(this);//This was the Issue, This line //should be kept above "this.state"
Alexandre Kirszenberg是对的,但另一件需要注意的重要事情是你把你的装订在哪里。我已经被这种情况困了好几天了(可能是因为我是初学者),但不像其他人,我知道bind(我已经应用了),所以我只是不明白为什么我仍然有这些错误。原来我把绑定的顺序弄错了。
另一个原因可能是我在this中调用了函数。State”,它不知道绑定,因为它恰好在绑定线之上,
以下是我的想法(顺便说一下,这是我第一次发帖,但我认为这很重要,因为我在其他地方找不到解决方案):
constructor(props){
super(props);
productArray=//some array
this.state={
// Create an Array which will hold components to be displayed
proListing:productArray.map(product=>{return(<ProRow dele={this.this.popRow()} prodName={product.name} prodPrice={product.price}/>)})
}
this.popRow=this.popRow.bind(this);//This was the Issue, This line //should be kept above "this.state"
这一点。在作为onChange道具传递之前,changeContent需要通过this.changeContent.bind(this)绑定到组件实例,否则函数体中的this变量将不会指向组件实例,而是指向窗口。看到函数::绑定。
当使用React时。createClass而不是ES6类,组件上定义的每个非生命周期方法都会自动绑定到组件实例。看到Autobinding。
注意绑定一个函数会创建一个新函数。您可以直接在呈现中绑定它,这意味着每次组件呈现时都会创建一个新函数,也可以在构造函数中绑定它,这只会触发一次。
constructor() {
this.changeContent = this.changeContent.bind(this);
}
vs
render() {
return <input onChange={this.changeContent.bind(this)} />;
}
引用设置在组件实例上,而不是在React上。refs:你需要将react .ref .someref改为this.ref .someref。您还需要将sendContent方法绑定到组件实例,以便该方法引用它。
Bind (this)可以解决这个问题,现在如果你不喜欢使用Bind,我们可以使用另外两种方法来实现这个目标。
1)和传统的方法一样,我们可以在构造函数中使用bind(this),这样当我们使用函数作为JSX回调时,this的上下文就是类本身。
class App1 extends React.Component {
constructor(props) {
super(props);
// If we comment out the following line,
// we will get run time error said `this` is undefined.
this.changeColor = this.changeColor.bind(this);
}
changeColor(e) {
e.currentTarget.style.backgroundColor = "#00FF00";
console.log(this.props);
}
render() {
return (
<div>
<button onClick={this.changeColor}> button</button>
</div>
);
}
}
2)如果我们将函数定义为带有箭头函数的类的属性/字段,我们就不需要再使用bind(this)了。
class App2 extends React.Component {
changeColor = e => {
e.currentTarget.style.backgroundColor = "#00FF00";
console.log(this.props);
};
render() {
return (
<div>
<button onClick={this.changeColor}> button 1</button>
</div>
);
}
}
3)如果我们使用箭头函数作为JSX回调,我们也不需要使用bind(this)。更进一步,我们可以传递参数。看起来不错,不是吗?但它的缺点是性能问题,详情请参阅ReactJS doco。
class App3 extends React.Component {
changeColor(e, colorHex) {
e.currentTarget.style.backgroundColor = colorHex;
console.log(this.props);
}
render() {
return (
<div>
<button onClick={e => this.changeColor(e, "#ff0000")}> button 1</button>
</div>
);
}
}
我已经创建了一个代码依赖来演示这些代码片段,希望它能有所帮助。