如何等待AJAX​​响应并且只有在渲染组件之后? [英] How to wait for AJAX response and only after that render the component?

查看:120
本文介绍了如何等待AJAX​​响应并且只有在渲染组件之后?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的React组件有问题。我认为在React呈现 ChildComp 组件之前,AJAX不会从外部服务器加载所有内容。

I have a problem with one of my React components. I think AJAX doesn't load all the content from external server before React renders the ChildComp component.

上面你可以看到来自服务器的响应树。这是我的组件代码:

Above you can see the tree of response which is coming from server. And this is my component's code:

var ChildComp = React.createClass({
  getInitialState: function(){
    return {
      response: [{}]
    }
  },
  componentWillReceiveProps: function(nextProps){
    var self = this;

    $.ajax({
      type: 'GET',
      url: '/subscription',
      data: {
        subscriptionId: nextProps.subscriptionId //1
      },
      success: function(data){
        self.setState({
          response: data
        });
        console.log(data);
      }
    });
  },
  render: function(){
      var listSubscriptions = this.state.response.map(function(index){
        return (
          index.id
        )
      });
      return (
        <div>
          {listSubscriptions}
        </div>
      ) 
  }
});

这工作正常,但如果我将我的回报改为:

This is working just fine, but if I change my return to:

  return (
     index.id + " " + index.order.id
  )

id未定义。以及订单对象的所有其他属性。为什么会这样?如果我 console.log 我在 success 函数后的响应,它会提供所有数据(如图片所示)。我的猜测是,当React渲染组件时,只加载第一个对象,然后加载所有其他内部对象。我真的不能说是不是这样(听起来很奇怪)也不能说怎么解决这个问题。

id is undefined. And all of the other properties of order object. Why is it like this? If I console.log my response after success function it gives all the data (like in picture). My guess is that only the first objects are loaded when React renders the component and after that all other inner objects are loaded. I can't really say if that's the case (sounds so weird) nor I can't say how to solve this out.

我也试过这样的事情

  success: function(data){
    self.setState({
      response: data
    }, function(){
      self.forceUpdate();
    })
  }.bind(this)

但在我的 console.log(data)被触发之前仍然会重新渲染。如何等待AJAX​​响应并且只有在渲染组件之后?

but still re-render happens before my console.log(data) is triggered. How to wait for AJAX response and only after that render the component?

推荐答案

这里是你的代码重做了一些修改过的部分的注释

Here's your code reworked with some comments of the modified parts

  getInitialState: function(){
    return {
      // [{}] is weird, either use undefined (or [] but undefined is better).
      // If you use [], you loose the information of a "pending" request, as 
      // you won't be able to make a distinction between a pending request, 
      // and a response that returns an empty array
      response: undefined
    }
  },







  loadSubscriptionData: function(subscriptionId){
    var self = this;

    // You probably want to redo the ajax request only when the 
    // subscriptionId has changed (I guess?)
    var subscriptionIdHasChanged = 
       (this.props.subscriptionId !== subscriptionId)

    if ( subscriptionIdHasChanged ) {
        // Not required, but can be useful if you want to provide the user
        // immediate feedback and erase the existing content before 
        // the new response has been loaded
        this.setState({response: undefined});

        $.ajax({
          type: 'GET',
          url: '/subscription',
          data: {
            subscriptionId: subscriptionId //1
          },
          success: function(data){

            // Prevent concurrency issues if subscriptionId changes often: 
            // you are only interested in the results of the last ajax    
            // request that was made.
            if ( self.props.subscriptionId === subscriptionId ) {
                self.setState({
                  response: data
                });
            }
          }
        });
     }
  },







  // You want to load subscriptions not only when the component update but also when it gets mounted. 
  componentDidMount: function(){
    this.loadSubscriptionData(this.props.subscriptionId);
  },
  componentWillReceiveProps: function(nextProps){
    this.loadSubscriptionData(nextProps.subscriptionId);
  },







  render: function(){

      // Handle case where the response is not here yet
      if ( !this.state.response ) {
         // Note that you can return false it you want nothing to be put in the dom
         // This is also your chance to render a spinner or something...
         return <div>The responsive it not here yet!</div>
      }

      // Gives you the opportunity to handle the case where the ajax request
      // completed but the result array is empty
      if ( this.state.response.length === 0 ) {
          return <div>No result found for this subscription</div>;
      } 


      // Normal case         
      var listSubscriptions = this.state.response.map(function(index){
        return (
          index.id
        )
      });
      return (
        <div>
          {listSubscriptions}
        </div>
      ) 
  }

这篇关于如何等待AJAX​​响应并且只有在渲染组件之后?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆