我正在用ES6 (使用BabelJS)编写一个简单的组件,但函数this.setState
不起作用。
典型的错误包括以下内容
无法读取未定义的属性“”setState“”
或
this.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
发布于 2015-04-11 21:09:14
this.changeContent
需要通过this.changeContent.bind(this)
绑定到组件实例上,然后才能作为onChange
prop传递,否则函数体中的this
变量不会引用组件实例,而会引用window
。参见Function::bind。
当使用React.createClass
而不是ES6类时,组件上定义的每个非生命周期方法都会自动绑定到组件实例。参见Autobinding。
注意,绑定一个函数会创建一个新函数。您可以直接在render中绑定它,这意味着每次呈现组件时都会创建一个新函数,或者将其绑定到您的构造函数中,该构造函数只会触发一次。
constructor() {
this.changeContent = this.changeContent.bind(this);
}
vs
render() {
return <input onChange={this.changeContent.bind(this)} />;
}
Ref是在组件实例上设置的,而不是在React.refs
上设置的:您需要将React.refs.someref
更改为this.refs.someref
。您还需要将sendContent
方法绑定到组件实例,以便this
引用它。
发布于 2015-12-03 02:15:59
Morhaus是正确的,但这可以在没有bind
的情况下解决。
您可以将arrow function与 proposal一起使用:
class SomeClass extends React.Component {
changeContent = (e) => {
this.setState({inputContent: e.target.value})
}
render() {
return <input type="text" onChange={this.changeContent} />;
}
}
因为箭头函数是在构造函数的作用域中声明的,并且因为箭头函数在其声明的作用域中维护this
,所以它都可以工作。这里的缺点是,这些不会是原型上的函数,它们都将在每个组件中重新创建。然而,这并不是什么坏处,因为bind
的结果是一样的。
发布于 2016-12-22 06:11:59
当从React.createClass()
组件定义语法过渡到扩展React.Component
的ES6类方式时,这个问题是我们大多数人首先遇到的问题之一。
这是由this
React.createClass()
extends React.Component
.与React.createClass()
中的上下文差异引起的
使用React.createClass()
将自动正确地绑定this
上下文(值),但在使用ES6类时情况并非如此。使用ES6方式(通过扩展React.Component
)时,this
上下文缺省情况下为null
。类的属性不会自动绑定到React类(组件)实例。
解决此问题的方法
我总共知道4种通用的方法。
在类构造函数中
SomeClass类扩展了React.Component {React.Component(Props){ super(props);this.handleClick = this.handleClick.bind(this);} handleClick() { console.log(this);// React组件实例} render() { }
SomeClass类扩展了React.Component { handleClick() { console.log(this);// React组件实例} render() {console.log( );}返回一个胖箭头函数。在箭头函数之前,每个新函数都定义了自己的this
值。但是,箭头函数不会创建自己的this
上下文,因此this
具有来自React组件实例的原始含义。因此,我们可以:
SomeClass类扩展了React.Component { handleClick() { console.log(this);// React组件实例} render() { return (< onClick={ () => this.handleClick() }> );}}
或
}
从‘autobind -
- [Autobind Decorator](https://github.com/andreypopp/autobind-decorator) is an NPM package which binds methods of a class to the correct instance of `this`, even when the methods are detached. The package **uses** **`@autobind`** **before methods to bind** **`this`** **to the correct reference** to the component's context.
’导入自动绑定;类SomeClass扩展了React.Component { @autobind handleClick() { console.log(this);// React组件实例} render() { return ( );}}
Autobind Decorator足够智能,可以让我们一次绑定组件类中的所有方法,就像方法1一样。
+ Class Autobind是另一个广泛使用的解决绑定问题的NPM包。与自动绑定装饰器不同,它不使用装饰器模式,但实际上只在构造函数中使用了一个函数,该函数自动将组件的方法绑定到正确的this
引用。
从“”SomeClass - autobind“”导入自动绑定;类返回扩展了构造函数{ React.Component (){ autobind(this);//或者如果只想绑定select函数: // autobind(this,'handleClick');} handleClick() { console.log(this);// React组件实例} render() { return ( );}}
PS:另一个非常相似的库是React Autobind。
推荐
如果我是你,我会坚持第一种方法。然而,一旦你的类构造函数中有了大量的绑定,我会建议你去探索第四种方法中提到的帮助器库。
其他
这与你的问题无关,而是你的shouldn't overuse refs。
你的第一个倾向可能是在你的应用中使用refs来“让事情发生”。如果是这种情况,花点时间仔细考虑一下状态应该在组件层次结构中的什么位置拥有。
出于类似的目的,就像您需要的那样,使用controlled component是首选方法。我建议你考虑使用你的Component state
。因此,您可以像这样简单地访问该值:this.state.inputContent
。
https://stackoverflow.com/questions/29577977
复制相似问题