生命周期componentWillReceiveProps被多次调用

kis*_*nio 11 reactjs react-router

我一直在实施Tyler McGinnis课程以学习反应.

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

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;
Run Code Online (Sandbox Code Playgroud)

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;
Run Code Online (Sandbox Code Playgroud)

现在在这里,componentWillReceiveProps被叫两次.我不明白为什么.从技术上讲,应该只召唤一次.我在MakeRequest方法中更新状态.这是在状态改变后第二次被召唤.

我还附上截图,以便更好地理解应用程序流程.

在此输入图像描述

更新:

我使用的是React-Router 3.0.3版.降级到2.0.0修复了它.哪个更奇怪.

Luc*_*ero 26

我不能告诉你为什么它被召唤两次,但我可以告诉你它应该没关系.问题是你没有比较道具的变化.如果这样做,代码将按您希望的方式运行:

componentWillReceiveProps: function(newProps) {
  if (newProps.params.city !== this.props.params.city) {
    this.makeRequest(newProps.params.city);
  }
},
Run Code Online (Sandbox Code Playgroud)

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

请注意,即使道具没有更改,React也可以调用此方法,因此如果您只想处理更改,请确保比较当前值和下一个值.当父组件导致组件重新呈现时,可能会发生这种情况.