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

当前回答

Morhaus是正确的,但这个问题可以不受约束地解决。

你可以将箭头函数与类属性建议一起使用:

class SomeClass extends React.Component {
  changeContent = (e) => {
    this.setState({inputContent: e.target.value})
  } 

  render() {
    return <input type="text" onChange={this.changeContent} />;
  }
}

因为箭头函数是在构造函数的作用域中声明的,而且因为箭头函数从它们的声明作用域中维护这一点,所以一切都可以正常工作。这里的缺点是这些不会是原型上的函数,它们都将与每个组件一起重新创建。然而,这并不是什么缺点,因为绑定也会产生同样的结果。

其他回答

您可以按照以下步骤解决这个问题

用更改sendContent函数

 sendContent(e) {
    console.log('sending input content '+this.refs.someref.value)
  }

使用以下命令更改呈现函数

<input type="text" ref="someref" value={this.state.inputContent} 
          onChange={(event)=>this.changeContent(event)} /> 
   <button onClick={(event)=>this.sendContent(event)}>Submit</button>

我的建议是使用箭头函数作为属性

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

因为第二种方法每次渲染调用都会生成新函数,实际上这意味着新指针和新版本的道具,如果你以后会关心性能,你可以使用React。PureComponent或React中。组件你可以覆盖shouldComponentUpdate(nextProps, nextState)和浅检查道具到达时

你可以用三种方法来解决这个问题

1.在构造函数本身中绑定事件函数,如下所示

import React from 'react'

class SomeClass extends React.Component {
  constructor(props) {
    super(props)
    this.state = {inputContent: 'startValue'}
    this.changeContent = this.changeContent.bind(this);
  }

  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

2.在调用时绑定

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.bind(this)}>Submit</button>
      </div>
    )
  }
}

export default SomeClass

3.通过使用箭头函数

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

此问题发生在react15.0之后,该事件处理程序没有自动绑定到组件。因此,无论何时调用事件处理程序,都必须手动将其绑定到组件。


有几种方法可以解决这个问题。但是你需要知道哪种方法是最好的,为什么?通常,我们建议将函数绑定到类构造函数中,或者使用箭头函数。

// method 1: use a arrow function
    class ComponentA extends React.Component {
      eventHandler = () => {
        console.log(this)
      }
      render() {
        return ( 
        <ChildComponent onClick={this.eventHandler} /> 
        );
      }

// method 2: Bind your functions in the class constructor.
    class ComponentA extends React.Component {
      constructor(props) {
        super(props);
        this.eventHandler = this.eventHandler.bind(this);
      }
      render() {
        return ( 
        <ChildComponent onClick={this.eventHandler} /> 
        );
      }

这两个方法不会在组件每次渲染时创建一个新函数。所以我们的ChildComponent将不会因为新的函数道具的改变而重新渲染,或者可能会产生性能问题。

这个问题的发生是因为。changeContent和onClick={this。sendContent}不绑定到组件实例的this。

还有另一种解决方案(除了在构造函数()中使用bind()之外)使用ES6中的箭头函数,这些函数与周围的代码共享相同的词法范围并维护它,所以你可以在render()中更改你的代码为:

render() {
    return (

        <input type="text"
          onChange={ () => this.changeContent() } /> 

        <button onClick={ () => this.sendContent() }>Submit</button>

    )
  }