在React JS中更新数组时this.setState和this.state的问题

时间:2017-08-16 02:17:14

标签: reactjs setstate

如果用户按下“+”按钮,我想在数据库中显示表格列表,并在按下“ - ”按钮时删除表格列表。我的代码是:

class DatabaseItem extends Component{
  constructor(){
    super();
    this.state = {
      tabList : [],
      plusIsNext : true
    };
  }

  flagOn(){
    this.setState({
      plusIsNext:!this.state.plusIsNext
    });
  }
  showTables(){
    if(this.state.plusIsNext){
      httpUtil.get(`http://localhost:4553/api?query=
      SELECT * FROM information_schema.tables WHERE table_schema='public'`,this.props.dbname).then(response => {
        this.setState({
          tabList:response.data
        })
      });
    }
    else{
      let arr = [];
      this.state.tabList = [];
      console.log(this.state.tabList);
    }
    this.flagOn();
  }
  render(){
    let sign = this.state.plusIsNext ? '+':'-';
    return(
      <div key ={this.props.dbname} >
        <button onClick ={() => {this.showTables()}}>{sign}</button><a>{this.props.dbname}</a>
        {this.state.tabList.map(table => {
          return(
            <div key = {table.table_name}>{table.table_name}</div>
          );
        })}
      </div>
    );
  }
}

现在我已经通过将空数组[]重新分配给this.state.tabList直接更新了tabList的值,它可以正常工作。如果我按下特定数据库的+按钮表,如果按下 - 按钮,列表就会消失。但是如果我使用setState将空数组重新分配给tabList,则tabList不会为空。

this.setState({
      tabList:[]
    })

let arr = [];
this.setState({
  tabList:arr
});

我错过了什么吗?

2 个答案:

答案 0 :(得分:2)

我认为你的问题是flagOn电话。因为JS是异步的,所以最好不要一次多次调用setState。发生的事情是它调用http请求,跳转到flagOn并调用setState,然后再次返回请求完成和setState。

我通过将这些调用合并到您的条件中来重构您的代码。如果我理解你的代码流程,这应该工作!

class DatabaseItem extends Component{
  constructor(){
    super();
    this.state = {
      tabList : [],
      plusIsNext : true
    };

    this.showTables = this.showTables.bind(this)
  }

  showTables(){
    if (this.state.plusIsNext) {
      httpUtil.get(`http://localhost:4553/api?query=
      SELECT * FROM information_schema.tables WHERE table_schema='public'`,this.props.dbname).then(response => {
        this.setState({ 
          tabList: response.data,
          plusIsNext: false
        })
      });
    } else {
      this.setState({ 
        tabList: [],
        plusIsNext: true
      })
    }
  }

  render(){
    let sign = this.state.plusIsNext ? '+':'-';
    return(
      <div key ={this.props.dbname} >
        <button onClick={this.showTables}>{sign}</button><a>{this.props.dbname}</a>
        {this.state.tabList.map(table => {
          return(
            <div key = {table.table_name}>{table.table_name}</div>
          );
        })}
      </div>
    );
  }
}

答案 1 :(得分:-1)

我猜你应该在获取数据或空列表之后只调用一次setState:

*showTables(){
  let _tabList = []
  let _plusNext = true

    if (this.state.plusIsNext) {
      yield httpUtil.get(`http://localhost:4553/api?query=
      SELECT * FROM information_schema.tables WHERE table_schema='public'`,this.props.dbname).then(response => {

          _tabList = response.data
          _plusNext = false
      });
    } 

    yield this.setState({ tabList: _tabList, plusIsNext: _plusNext})
  }

编辑: 将函数转换为生成函数。