【问题标题】:reactjs render() not triggered after promise resolves this.setState is re-assigned承诺解决后未触发reactjs render() this.setState 被重新分配
【发布时间】:2017-02-18 19:05:25
【问题描述】:

我有一个函数,它在下面设置一个 InitialState,然后使用 componentWillMount 和 fetchData 进行 api 调用以分配数据 this.state。然而,当 this.setState() 完成后,渲染函数不会被新的 this.state 数据触发,我的函数如下:

var Home = React.createClass({
  getInitialState: function() {
    return {
      city: '',
      weather: '',
      temperature: 0,
      humidity: 0,
      wind: 0,
    }
  },
  fetchData: function() {
    apiHelpers.getCityInfo()
    .then(function (response){
      this.setState({ data: response
      })
    }.bind(this))
  },
  componentWillMount: function(){
    this.fetchData();
  },
  render: function () {
    return (
      <div className="container">
      <Cities data={this.state.data} />
      </div>
    )
  }
});

【问题讨论】:

  • 你怎么知道渲染没有被触发?也许它被触发但呈现相同的结果?
  • 嗨,我在 fetchData 和 render 中插入了一个 console.log,promise 解决了,setState 被执行,但是 render 方法不会重新运行并使用新的 this.state 值更新
  • 那么,答案应该对您有所帮助。 componentWillMount 很少使用。

标签: javascript reactjs components render setstate


【解决方案1】:

根据反应文档

componentWillMount 被调用一次,都在client and server 上,在初始渲染发生之前。如果您在此方法中调用 setState,render() 将看到更新后的状态,并且尽管状态发生变化,但只会执行 once

要解决此问题,请使用 componentDidMount 代替 componentWillMount。由于您正在更新状态变量 data 中的响应,因此请先定义它,然后无需定义其他状态变量,只需将数据传递到 child component 并像现在一样更新状态。

var Home = React.createClass({
  getInitialState: function() {
    return {
      data: ''
    }
  },
  fetchData: function() {
    apiHelpers.getCityInfo()
    .then(function (response){
      this.setState({ data: response
      })
    }.bind(this))
  },
  componentDidMount: function(){
    this.fetchData();
  },
  render: function () {
    return (
      <div className="container">
      <Cities data={this.state.data} />
      </div>
    )
  }
});

【讨论】:

  • 嗨 Shubham,componentDidMount() 根本不运行 fetchData 函数。
  • 你试过console.log()到fetchData函数中看是否运行
  • 嗨,是的,共同 componentDidMount 和 componentWillMount 没有运行 fetchData 函数
  • 是不是没有运行 fetchdata 或者 apihelpers.getcityinfo 可以查一下
  • 它正在运行 fetchData 和 apihelpers,但是 render() 在 apiHelpers 承诺解决之前运行,一旦承诺解决,render() 就不会再次运行
【解决方案2】:

初始状态没有data。将您的代码更改为-

fetchData: function() {
    apiHelpers.getCityInfo()
     .then(function (response){
      this.setState({
          city: response.city,
          weather: response.weather,
          temperature: response.temperature,
          humidity: response.humidity,
          wind: response.wind,
       })
    }.bind(this))
  },

期望您的 api 响应包含城市、天气等对象......

【讨论】:

    猜你喜欢
    • 2017-08-10
    • 2018-12-11
    • 2020-03-16
    • 2018-04-02
    • 2020-10-22
    • 2014-12-15
    • 2016-04-05
    • 2013-12-27
    • 2014-03-28
    相关资源
    最近更新 更多