【问题标题】:How to render a component without calling setState or making componentWillUpdate to be executed in React?如何在不调用 setState 或在 React 中执行 componentWillUpdate 的情况下渲染组件?
【发布时间】:2016-07-14 18:28:56
【问题描述】:

所以,假设我有 2 个 React 组件,如下所示:

var Parent = React.createClass({
   getInitialState: function(){
      return ({
       child: <Children state="someState" />      
      });      
   },

  parentFunction: function() {
     this.setState({
       child: <Children state="otherState" />
     });
  },

  render: function() {
      return (
              <div>
              {this.state.child}                  
              </div>
      );
  }

  //...other methods
});

var Children = React.createClass({
   componentWillMount: function() {
      this.getData();
   },

   componentWillUpdate: function() {
      this.getData();
   }

   getData: function() {
      var that = this;

      $.getJSON("https://some.url", function(result){
           //Do something with result         

           that.setState();
      }); 


   }

   //other methods ....

});

Parent 首次渲染时,Child 也首次渲染。因此,Children 的 componentWillMount 被执行,然后它又调用 Children 的 getData。由于 getData 调用 getJSON 这是异步函数,因此它不能“按时”返回结果,以便第一次呈现儿童。因此,我的解决方案是在 getJSON 完成结果后调用 setState() 以使 Children 再次呈现。到目前为止一切正常。

但是当我调用 parentFunction 来更新 Children 时,问题就出现了。由于 Children 被更新,它的 componentWillUpdate 将被执行,因此 getData() 被调用。但是 getData() 在处理完结果后又会调用 setState() 。 setState() 使 componentWillUpdate 被执行。这就是我陷入无限循环的原因。

我正在寻找一种无需调用 setState 或执行 componentWillUpdate 即可呈现组件的方法。但我还没有找到。 我不知道如何解决这个问题。任何帮助,将不胜感激。

【问题讨论】:

  • 这里的核心问题是发出ajax请求来响应组件更新是不行的。您需要弄清楚实际应该触发 ajax 请求的内容,例如道具与下一个渲染不同或用户按下按钮等。
  • 使用组件会收到道具。检查 React 文档。

标签: javascript reactjs


【解决方案1】:

无需调用 setState 就无需寻找渲染方式。

为避免循环,只需使用 componentWillReceiveProps() 代替 componentWillUpdate,如 React documentation 中所述。

但是,您甚至可以测试组件是否真的应该更新,使用类似以下的模式:

var Children = React.createClass({
    componentWillMount: function() {
        this.getData();
    },

    componentWillReceiveProps: function(nextProps) {
        // some sort of logic that defines if new 
        // props are different than the previous ones
        if(nextProps.data !== this.props.data)
        {
            this.getData();
        }
    }

    getData: function() {
        var that = this;

        $.getJSON("https://some.url", function(result){
            //Do something with result         

            that.setState();
        }); 
    }
}

据我说,您还以错误的方式使用了父母的状态。

状态应该包含关于组件本身的数据和属性,而不是其他组件。

这样重写会很有帮助:

var Parent = React.createClass({
   getInitialState: function(){
      return ({
       something: [] // example
      });      
   },

  parentFunction: function() {
     this.setState({
       something: [12] // example
     });
  },

  render: function() {
      return (
              <div>
                   <Children state={this.state.something} />
              </div>
      );
  }

  //...other methods
});

希望这会有所帮助。

【讨论】:

  • 谢谢!你刚刚救了我的命。 :)
  • 很高兴它有帮助:)
猜你喜欢
  • 2015-08-18
  • 2018-03-27
  • 2020-08-18
  • 2021-03-10
  • 1970-01-01
  • 2017-07-23
  • 1970-01-01
  • 2021-09-22
  • 1970-01-01
相关资源
最近更新 更多