Reactjs неожиданный бесконечный цикл с рендером

5

Я использую React для реализованного компонента Include. Он загружает контент из url. Этот тест работает, но также создает неожиданный бесконечный цикл с рендерингом... почему?

<script type="text/jsx">
  /** @jsx React.DOM */
  var Include = React.createClass({
    getInitialState: function() {
      return {content: 'loading...'};
    },
    render: function() {
      var url = this.props.src;
      $.ajax({
        url: url,
        success: function(data) {
          this.setState({content: data});
        }.bind(this)
      });
      return <div>{this.state.content + new Date().getTime()}</div>;
    }
  });

  var Hello = React.createClass({
    render: function() {
        return <Include src="hello.txt" />;
    }
  });
  React.renderComponent(
    <Hello />,
    document.getElementById('hello')
  );
</script>
Теги:

2 ответа

4

Это более надежный компонент Include. Различия,

  • рендер должен быть чистым (не может делать ajax там)
  • getInitialState должен быть чистым
  • если опорный сигнал является динамическим, например. <Include url={this.state.x} />, он должен обновить
var Include = React.createClass({
  getInitialState: function() {
    return {content: 'loading...'};
  },
  componentDidMount: function(){ 
    this.updateAJAX(this.props.url); 
  },
  componentWillReceiveProps: function(nextProps){
    // see if it actually changed
    if (nextProps.url !== this.props.url) {
      // show loading again
      this.setState(this.getInitialState);

      this.updateAJAX(nextProps.url);
    }
  },
  updateAJAX: function(url){
    $.ajax({
      url: url,
      success: function(data) {
        this.setState({content: data});
      }.bind(this)
    });
  },
  render: function() {
    return <div>{this.state.content}</div>;
  }
});

var Hello = React.createClass({
  render: function() {
    return <Include src="hello.txt" />;
  }
});
1

Я понял, что рендер выполняется много раз, так что это не лучшее место для моего вызова ajax (-_-) '

Этот способ отлично работает:

<script type="text/jsx">
  /** @jsx React.DOM */
  var Include = React.createClass({
    getInitialState: function() {
      var url = this.props.src;
      $.ajax({
        url: url,
        success: function(data) {
          this.setState({content: data});
        }.bind(this)
      });
      return {content: 'loading...'};
    },
    render: function() {
      return <div>{this.state.content + new Date().getTime()}</div>;
    }
  });

  var Hello = React.createClass({
    render: function() {
        return <Include src="hello.txt" />;
    }
  });
  React.renderComponent(
    <Hello />,
    document.getElementById('hello')
  );
</script>

Спасибо, что прочитали!

  • 2
    Рад видеть, что вы решили проблему! Одно небольшое предложение, которое я бы порекомендовал, - переместить вызов ajax в метод componentWillMount. Результат тот же, но использование метода componentWillMount приводит к лучшему разделению проблем. Я приложил скрипку, чтобы вы могли, что я имею в виду. Ps - Реакция потрясающая Вот jsfiddle
  • 1
    @user3508122 user3508122 Я считаю, что componentDidMount подходит для этого. Он используется в официальном уроке . Единственная причина, по которой я могу думать, это то, что componentWillMount вызывается при использовании renderComponentToString (то есть рендеринг сервера).
Показать ещё 1 комментарий

Ещё вопросы

Сообщество Overcoder
Наверх
Меню