首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >无法访问事件处理程序内的React实例(this

无法访问事件处理程序内的React实例(this
EN

Stack Overflow用户
提问于 2015-04-11 20:41:39
回答 18查看 81.1K关注 0票数 239

我正在用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
EN

回答 18

Stack Overflow用户

回答已采纳

发布于 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引用它。

票数 268
EN

Stack Overflow用户

发布于 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的结果是一样的。

票数 105
EN

Stack Overflow用户

发布于 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种通用的方法。

在类构造函数

  1. Bind您的函数。许多人认为这是一种最佳实践方法,它完全避免接触JSX,并且不会在每个组件重新呈现时创建新函数。

SomeClass类扩展了React.Component {React.Component(Props){ super(props);this.handleClick = this.handleClick.bind(this);} handleClick() { console.log(this);// React组件实例} render() { }

  • Bind ( );}内联函数。你仍然可以在一些教程/文章/等等中找到使用这种方法的地方,所以你意识到它是很重要的。它与#1的概念相同,但请注意,绑定一个函数会在每次重新渲染时创建一个新函数。

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() }> );}}

}

  • Use SomeClass扩展了React.Component { handleClick = () => { console.log(this);// React组件实例} render() { return ( );}}

  • Use实用函数库以自动绑定函数。有一些实用程序库,它们会自动为您完成这项工作。以下是一些流行的,仅举几个:

从‘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

票数 57
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/29577977

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档