反应TypeError:“ _ this2.setState不是函数”?

时间:2018-11-11 13:48:48

标签: javascript reactjs axios

我知道这个问题经常被问到,我确实检查了提供的大多数其他答案,但是我仍然无法找出为什么会收到此错误。

情况:

我有一个textinput类,其中有一个供用户输入名称的简单表格。当用户提交按钮时,将调用对我的后端的REST调用,并且UI应显示用户名。

我已覆盖componentDidMount类的函数App,以便在加载页面时对后端进行初始调用。此调用有效,我从后端得到正确答案,并且UI得到更新。

但是当我从TextInput类进行呼叫时,出现错误消息:

  

this2.setState不是函数

我相信这是因为我从另一个类调用了函数,并且this state的设置不正确。我试图束缚所有东西,但这并没有改变任何东西。如果有人知道我在做什么错,那将非常有帮助!

我有以下课程:

import React, { Component } from 'react';
import logo from './logo.svg';
import Greeting from './components/greeting';
import TextInput from './components/textInput';
import './App.css';

const axios = require('axios');

class App extends Component {
  constructor(props) {
    super(props);
    this.state = {name: "World"};
    this.getFormattedNameFromBackend.bind(this);
    this.setState.bind(this);
  }

  componentDidMount() {
    this.getFormattedNameFromBackend(this.state.name);
  }

  getFormattedNameFromBackend(name) {
    axios({
      method:'get',
      url:'http://localhost:8080/hello?name=' + name
    }).then((response) => {
      this.setState({ name : response.data.name});
    }).catch(function(error){
      console.log(error);
    });
  }


  render() {
    return (
      <div className="App">
        <header className="App-header">
          <img src={logo} className="App-logo" alt="logo" />
          <Greeting data={this.state}/>
          <TextInput callBack = {this.getFormattedNameFromBackend}/>
        </header>
      </div>
    );
  }

}

export default App;

这是在axios rest调用中出现错误的主要类。

第二堂课是这样的

import React, { Component } from 'react';

export default class TextInput extends Component {
    constructor(props) {
      super(props);
      this.state = {value: ''};

      this.handleChange = this.handleChange.bind(this);
      this.handleSubmit = this.handleSubmit.bind(this);
    }

    handleChange(event) {
      this.setState({value: event.target.value});
    }

    handleSubmit(event) {
      this.props.callBack(this.state.value);

      event.preventDefault();
    }

    render() {
      return (
        <form onSubmit= {this.handleSubmit}>
          <label>
            Name:
            <input type="text" value={this.state.value} onChange={this.handleChange} />
          </label>
          <input type="submit" value="Submit" />
        </form>
      );
    }
  }

所以问题是,如何在getFormattedNameFromBackend方法中调用正确的方法?

已解决:

错误是将Textinputfield的props设置为错误。正确的应该是

<TextInput callBack = {(name)=>this.getFormattedNameFromBackend(name)}/>

2 个答案:

答案 0 :(得分:1)

万一其他人遇到这个问题,https://reactjs.org/docs/handling-events.html会很好地解释为什么会发生这种情况。

简而言之,调用事件回调时,this没有绑定。

解决此问题的最简单方法是将其括起来: onSubmit={(e) => {this.handleSubmit(e)}(尽管每次都会创建一个新的函数实例,所以在使用此方法时要小心。)

答案 1 :(得分:0)

您完全可以通过this避免绑定来解决问题,但是您最初的问题是该行

    this.getFormattedNameFromBackend.bind(this);

不完全按照您的想法去做。
.bind()返回一个包装原始功能的新功能,但是您对该新功能不做任何事情。 .bind()不会修改原始功能,因此this.getFormattedNameFromBackend仍然不受约束,这就是<TextInput callBack = {this.getFormattedNameFromBackend}/>无法正常工作的原因。

如果您将该行写为:

    this.getFormattedNameFromBackend = this.getFormattedNameFromBackend.bind(this);

...(就像您在TextInput类中所做的那样),它将可以正确绑定,并且callBack = {this.getFormattedNameFromBackend}可以正常工作。

就像我说的那样,通过将其写为callBack = {() => this.getFormattedNameFromBackend()}可以避免绑定问题,因此只需删除this.getFormattedNameFromBackend.bind(this);(顺便说一句,this.setState.bind(this);也是毫无意义的)