【问题标题】:Issues with this.setState and this.state while updating an array in React JS在 React JS 中更新数组时 this.setState 和 this.state 的问题
【发布时间】:2017-08-16 02:17:14
【问题描述】:

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

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

我错过了什么吗?

【问题讨论】:

    标签: reactjs setstate


    【解决方案1】:

    我认为您的问题是 flagOn 调用。因为 JS 是异步的,所以最好不要一次多次调用 setState。发生的情况是它调用 http 请求,跳转到 flagOn 并调用 setState,然后在完成后返回 request 并再次 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>
        );
      }
    }
    

    【讨论】:

    • 谢谢。我现在明白了。这解决了我的问题。
    【解决方案2】:

    我猜你应该只调用一次 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})
      }
    

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

    【讨论】:

    • 我看到我的代码出了什么问题。纠正它。 ( : 而不是 = )
    • 您的代码有问题。 httpUtil.get 是异步的。这意味着当this.setState 被调用时,httpUtil.get 可能还没有返回(甚至没有被执行)。
    • 谢谢@WinChiu。我已经编辑了我的代码。希望它现在应该可以工作
    • yield 有什么作用?并且不会删除 else 条件导致下面的 setState 被执行,而不管 plusIsNext 的价值如何?
    • 我写了一个生成器函数。 yield 确保在下一个yield 之前完成执行,因此可以作为同步执行。如果我查看您的代码,您会在两个地方调用setState - ifelse。我所做的是,定义了您在else 条件下所做的变量和值。如果,if 条件为真,您的 tabList 和 plusIsNext 将有值,否则状态将有空选项卡列表和 false(与 else 条件相同)
    猜你喜欢
    • 2023-03-18
    • 1970-01-01
    • 2017-05-23
    • 1970-01-01
    • 2020-03-19
    • 2016-06-22
    • 2019-02-25
    • 1970-01-01
    相关资源
    最近更新 更多