我正在用ES6编写一个简单的组件(使用BabelJS),函数this.setstate
不工作。
典型的错误包括
无法读取未定义的属性“set state”
或
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
当从react.createClass()
组件html" target="_blank">定义语法过渡到扩展react.component
的ES6类方式时,这个问题是我们大多数人首先经历的事情之一。
它是由react.createClass()
与extends react.component
中的this
上下文差异引起的。
使用react.createClass()
会自动正确绑定this
上下文(值),但使用ES6类时并非如此。当使用ES6方法(通过扩展react.component
)时,this
上下文默认为null
。类的属性不会自动绑定到React类(组件)实例。
我总共知道4种通用方法。
>
在类构造函数中绑定函数。许多人认为这是一种最佳实践方法,它完全避免接触JSX,并且不会在每个组件重新呈现时创建新的函数。
class SomeClass extends React.Component {
constructor(props) {
super(props);
this.handleClick = this.handleClick.bind(this);
}
handleClick() {
console.log(this); // the React Component instance
}
render() {
return (
<button onClick={this.handleClick}></button>
);
}
}
将函数内联绑定。您仍然可以在一些教程/文章/等等中找到这种方法,所以了解它是很重要的。它的概念与#1相同,但要注意,绑定一个函数会在每次重新呈现时创建一个新函数。
class SomeClass extends React.Component {
handleClick() {
console.log(this); // the React Component instance
}
render() {
return (
<button onClick={this.handleClick.bind(this)}></button>
);
}
}
使用胖箭头函数。在箭头函数之前,每个新函数都定义了自己的this
值。但是,arrow函数并不创建自己的this
上下文,因此this
具有来自React组件实例的原始含义。因此,我们可以:
class SomeClass extends React.Component {
handleClick() {
console.log(this); // the React Component instance
}
render() {
return (
<button onClick={ () => this.handleClick() }></button>
);
}
}
或
class SomeClass extends React.Component {
handleClick = () => {
console.log(this); // the React Component instance
}
render() {
return (
<button onClick={this.handleClick}></button>
);
}
}
使用实用函数库自动绑定函数。有一些实用程序库可以自动为您完成这项工作。下面是一些流行的,只提几个:
>
autobind Decorator是一个NPM包,它将类的方法绑定到this
的正确实例,即使方法被分离时也是如此。包使用@autobind
before方法将this
绑定到对组件上下文的正确引用。
import autobind from 'autobind-decorator';
class SomeClass extends React.Component {
@autobind
handleClick() {
console.log(this); // the React Component instance
}
render() {
return (
<button onClick={this.handleClick}></button>
);
}
}
Autobind装饰器足够聪明,可以让我们一次绑定组件类中的所有方法,就像方法#1一样。
类Autobind是另一个被广泛用于解决此绑定问题的NPM包。与Autobind Decorator不同,它不使用Decorator模式,而实际上只是在构造函数中使用一个函数,该函数自动将组件的方法绑定到this
的正确引用。
import autobind from 'class-autobind';
class SomeClass extends React.Component {
constructor() {
autobind(this);
// or if you want to bind only only select functions:
// autobind(this, 'handleClick');
}
handleClick() {
console.log(this); // the React Component instance
}
render() {
return (
<button onClick={this.handleClick}></button>
);
}
}
附注:其他非常相似的库是React Autobind。
如果我是你,我会坚持第一条。但是,一旦在类构造函数中得到大量绑定,我将建议您探索方法#4中提到的一个帮助器库。
这与你的问题无关,但你不应该过度使用refs。
你的第一个倾向可能是使用refs在你的应用程序中“使事情发生”。如果是这种情况,花点时间,更批判性地考虑一下状态应该在组件层次结构中的哪个位置拥有。
出于类似的目的,就像您需要的那样,使用受控组件是首选的方式。我建议您考虑使用组件state
。因此,您可以简单地访问值,如下所示:this.state.inputContent
。
Morhaus是正确的,但这可以在没有bind
的情况下解决。
您可以将箭头函数与类属性建议一起使用:
class SomeClass extends React.Component {
changeContent = (e) => {
this.setState({inputContent: e.target.value})
}
render() {
return <input type="text" onChange={this.changeContent} />;
}
}
因为箭头函数是在构造函数的作用域中声明的,而且箭头函数在其声明作用域中维护this
,所以它都可以工作。这里的缺点是这些将不是原型中的函数,它们都将与每个组件一起重新创建。但是,这并不是什么坏处,因为bind
会导致同样的结果。
this.ChangeContent
在作为OnChange
道具传递之前,需要通过this.ChangeContent.bind(this)
绑定到组件实例,否则函数主体中的this
变量将不引用组件实例,而是引用Window
。请参阅Function::Bind。
当使用react.createClass
而不是ES6类时,在组件上定义的每个非生命周期方法都自动绑定到组件实例。请参见自动绑定。
请注意,绑定一个函数会创建一个新函数。您可以在render中直接绑定它,这意味着每次组件呈现时都会创建一个新函数,也可以在您的构造函数中绑定它,这只会激发一次。
constructor() {
this.changeContent = this.changeContent.bind(this);
}
VS
render() {
return <input onChange={this.changeContent.bind(this)} />;
}
Refs是在组件实例上设置的,而不是在react.Refs
上设置的:您需要将react.Refs.someRef
更改为this.Refs.someRef
。您还需要将sendcontent
方法绑定到组件实例,以便this
引用它。
问题内容: 我正在用ES6(使用BabelJS)编写一个简单的组件,并且功能无法正常工作。 典型的错误包括类似 无法读取未定义的属性“ setState” 要么 this.setState不是一个函数 你知道为什么吗?这是代码: 问题答案: 在作为prop 传递之前,需要先通过绑定到组件实例,否则函数主体中的变量将不会引用组件实例,而会引用。参见Function :: bind 。 当使用而不是E
问题内容: 我正在用ES6(使用BabelJS)编写一个简单的组件,并且功能无法正常工作。 典型的错误包括类似 无法读取未定义的属性“ setState” 要么 this.setState不是一个函数 你知道为什么吗?这是代码: 问题答案: 在作为prop 传递之前,需要先通过绑定到组件实例,否则函数主体中的变量将不会引用组件实例,而是指向。参见Function :: bind 。 当使用而不是E
我试图创建一个反应组件,这是一个文本输入。当有人按下回车键时,必须调用mymethod()。但是在handleKeyPress,我不能访问类范围。我怎样才能解决这个问题?
我想在JavaFX中制作一个程序,其中包含一个按钮,单击该按钮时,将创建一个圆并将其添加到形状的ArrayList中。以下是我的代码: 我的问题是-如何从内部句柄方法访问“circle1”?在JavaScript中,我们使用e.currentTarget。 我无法声明“Circle1”最终版本,因为我需要在之后更改它。
我在主页组件中有这个代码,当按下向下/向上箭头键时,什么也没有发生。我刚刚意识到,当用ctrl键按箭头键时,eventhandler可以正常工作。我到处找,但什么也没找到。有人能帮忙吗?我的浏览器是Chrome v.96。React版本17.0.2,节点v.16.13.1