【问题标题】:Lifecycle componentWillReceiveProps is called multiple times生命周期组件WillReceiveProps 被多次调用
【发布时间】:2017-09-05 01:57:25
【问题描述】:

我一直在实现 Tyler McGinnis curriculum 来学习 react。

这是一个天气应用程序。而且我在调试奇怪的行为时遇到了麻烦。我很确定我正在做的事情很愚蠢,或者我可能错过了一条信息。

SearchContainer 是 ParentContainer,

var React = require("react");
var Search = require("../components/Search");

var SearchContainer = React.createClass({
  propTypes: {
    formType: React.PropTypes.string
  },
  contextTypes: {
    router: React.PropTypes.object.isRequired
  },
  getDefaultProps: function() {
    return {
      formType: "form"
    }
  },
  getInitialState: function() {
    return {
      city: ""
    }
  },
  handleSearchSubmit: function(e) {
    e.preventDefault();
    this.context.router.push('/forecast/' + this.state.city);
  },
  handleCityChange: function(e) {
    this.setState({
      city: e.target.value
    });
  },
  render() {
    return (
      <Search
        formType={this.props.formType}
        city={this.state.city}
        onCityChange={this.handleCityChange}
        onSearchSubmit={this.handleSearchSubmit}/>
    );
  }
})

module.exports = SearchContainer;

SearchContainer 更改上下文并切换到ForecastContainer

var React = require("react");

var Forecast = require("../components/Forecast");
var Api = require("../helpers/Api");

var ForecastContainer = React.createClass({
  getInitialState: function() {
    return {
      isLoading: true,
      data: []
    }
  },
  makeRequest: function(city) {
    this.setState({
          isLoading: true,
    });
    Api.getDayForecast(city).then( function(data) {
        this.setState({
          isLoading: false,
          data: data.data.list
        });
    }.bind(this) );
  },
  componentDidMount: function() {
    this.makeRequest(this.props.params.city);
  },
  componentWillReceiveProps: function(newProps) {
    this.makeRequest(newProps.params.city);
  },
  render() {
    return (
      <Forecast isLoading={this.state.isLoading} data={this.state.data} />
    )
  }
});

module.exports = ForecastContainer;

现在,componentWillReceiveProps 被调用了两次。我不明白为什么。从技术上讲,它应该只调用一次。我正在更新MakeRequest 方法中的状态。状态改变后第二次调用。

我还附上了屏幕截图,以便更好地了解应用程序流程。

更新:

我使用的是 React-Router 版本 3.0.3。降级到 2.0.0 可以修复它。更奇怪的是。

【问题讨论】:

  • 所以我只是将 react-router 版本降级到 2.0.0,现在 componentWillReceiveProps 被调用一次。这很奇怪。是否与新的 React-Router 有关?

标签: reactjs react-router


【解决方案1】:

我不能告诉你为什么它被调用了两次,但我可以告诉你这应该不重要。问题是你没有比较道具的变化。如果你这样做,代码将按照你想要的方式运行:

componentWillReceiveProps: function(newProps) {
  if (newProps.params.city !== this.props.params.city) {
    this.makeRequest(newProps.params.city);
  }
},

另见官方 ReactJS 文档,其中指出(强调我的): https://facebook.github.io/react/docs/react-component.html#componentwillreceiveprops

请注意,即使 props 没有,React 也可能会调用此方法 已更改,因此如果您请务必比较当前值和下一个值 只想处理更改。父组件时可能会出现这种情况 导致您的组件重新渲染。

【讨论】:

  • 哦,是的,我就是这么想的。我做了一个比较,然后继续。我不知道为什么我对这个很挑剔。仅通过降级 react-router 版本,它也可以工作,这很有趣。
  • @kishanio 我的猜测是新路由器由于某种原因会导致文档中提到的重新渲染之一。然而,这是允许行为而不是错误,所以如果没有令人信服的理由不这样做,我会回到路由器 v3.0.3。
  • @Lucero 工作完美!我很难找到一种方法来限制它。
猜你喜欢
  • 2017-03-09
  • 2019-07-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-11-25
  • 2018-03-11
  • 1970-01-01
相关资源
最近更新 更多