尝试更新状态onClick导致“ this.setState不是函数”错误

时间:2019-04-27 22:26:46

标签: reactjs

在我的SideMenuRow组件内的以下SideMenuContainer子div中,我正在调用changeInfoList方法。该方法位于父App.js中。

在App.js中:

<SideMenuContainer changeInfoList={this.changeInfoList} genInfoList={this.state.genInfoList} groupedObjectsList={this.state.groupedObjectsList}/>

在SideMenuContainer.js中:

<SideMenuRow onClick={this.props.changeInfoList(genInfoElement.name)}>

以下是App.js代码的相关部分,涉及方法和状态:

  constructor(props) {
    super(props);
    this.state = {
      genInfoList: [],
      groupedObjectsList: [],
      cardInfo: {
        name: data[0].name
      },
      data: []
    };
  }

  changeInfoList(rowName){
    //change the card rendered based on which row is clicked
    this.setState({
      cardInfo: {
        name: rowName
      }
    })
  }

我构造这种不允许setState起作用的方法的方式有何不正确?

2 个答案:

答案 0 :(得分:2)

您收到此错误,因为关键字this并不指向组件的执行上下文,并且它的当前执行上下文没有名为setState()的方法

您可以通过以下两种方法进行处理:

1)定义如下箭头功能:

  const changeInfoList = (rowName) => {
    //change the card rendered based on which row is clicked
    this.setState({
      cardInfo: {
        name: rowName
      }
    })
  }

通过使用箭头功能(不绑定this),this关键字现在指向最近的对象,在本例中为您的类组件,该对象具有setState()方法。

2)将当前函数绑定到组件的构造函数中。

 constructor(props) {
    super(props);
    this.state = {
      genInfoList: [],
      groupedObjectsList: [],
      cardInfo: {
        name: data[0].name
      },
      data: []
    };

 this.changeInfoList = this.changeInfoList.bind(this)
  }

这明确地告诉您的函数,它现在指向类组件的上下文。

现在假设您执行了以下任一步骤,则必须将changeInfoList传递到子组件中:

在App.js中:

<SideMenuContainer changeInfoList={this.changeInfoList} genInfoList={this.state.genInfoList} groupedObjectsList={this.state.groupedObjectsList}/>

在SideMenuContainer中:

<SideMenuRow onClick={() => { this.props.changeInfoList(genInfoElement.name) }}>

答案 1 :(得分:1)

 constructor(props) {
    super(props);
    this.state = {
      genInfoList: [],
      groupedObjectsList: [],
      cardInfo: {
        name: data[0].name
      },
      data: []
    };
// Bind the function
this.changeInfoList = this.changeInfoList.bind(this)
  }

  changeInfoList(rowName){
    //change the card rendered based on which row is clicked
    this.setState({
      cardInfo: {
        name: rowName
      }
    })
  }