React组件获取请求在一个中进行,或者点击迟到

时间:2016-09-29 16:37:40

标签: javascript http reactjs get

这个很难解释,但基本上当点击某个组件时,我会为另一个组件的某些数据发出get请求。然而,只有在点击几下后才会这样做。 我应该承认,如果我提出请求的地方甚至是正确的,我也不能100%确定,所以如果是这样的话请告诉我如何解决这个问题。这是代码:

var ChangeLogData = React.createClass({

  getInitialState: function () {
    return {
        content: {},
    }
  },


  render: function () {
    var _this=this;

    $.get(this.props.source, function (data) {
        var log = $.parseJSON(data);
        _this.state.content = log;

    }.bind(this));

    return (

        <div>
            {_this.state.content[0]}
        </div>
 );
 }

});

window.ChangeLog = React.createClass({


render: function () {
    return (
            <div>
                <ChangeLogData name={this.props.params.name}
                               source={currentUrl + "/changelog/" + 
                               this.props.params.name}/>
            </div>
    );
}

});

编辑:我还应该补充说,似乎大多数人都建议在componentWillMount上执行http请求,但如果我这样做,请求只能运行一次。

编辑2:以下是调用事件的位置代码:

var AboutItem = React.createClass({

render: function () {
    return (
        <ListGroup>
            {this.props.list.map(function (listValue,key) {
                var link = currentUrl + "/changelog/" + listValue.split(' ')[0];
                return <ListGroupItem key={key} className="module"
                                                      bsStyle="warning">
                    {listValue}
                </ListGroupItem>
            })}
        </ListGroup>
    );
}

});

我想这个想法是,用户将点击一个项目(动态生成),当单击该项目时,它将向ChangeLog组件发送必须执行get请求的数据。那么我将把我的事件处理程序放在哪里呢?

4 个答案:

答案 0 :(得分:0)

我认为问题在于它没有被正确调用,因为jquery是异步的......

var jqxhr = $.get( "example.php", function() {
  alert( "success" );
})
  .done(function() {
    // PUT YOUR CALLBACK CODE HERE WITH THE RESULTS
  })
  .fail(function() {
    alert( "error" );
  })
  .always(function() {
    alert( "finished" );
  });

并更新.done()

中的状态

答案 1 :(得分:0)

您不应该在渲染方法中发出请求。您也不应该通过this.state直接修改状态,而是使用this.setState()。您似乎也没有添加任何onClick处理程序。

您可以执行以下操作来触发onClick上的请求:

var ChangeLogData = React.createClass({

   getInitialState: function () {
    return {
       content: {},
   }
 },

 handleClick: function() {
    $.get(this.props.source, function (data) {
      var log = $.parseJSON(data);
      this.setState( { content: log } );

   }.bind(this));

 }

 render: function () {
   return (

      <div onClick = { this._handleClick } >
           {_this.state.content[0]}
       </div>
 );
}

如果要在组件装载上执行此操作,可以在检索数据时将其放入componentDidMount()并调用setState。这将导致组件使用内容重新呈现

答案 2 :(得分:0)

  • 首先:get请求是异步的,所以当你收到回复时,DOM已经呈现了。
  • 第二:永远不要更新渲染方法中的状态,如果它有效并且你没有收到错误信息,你很可能会创建一个无限循环,render =&gt; updateState =&gt; render =&gt; udpateState ...

您有多个选项,您可以在onClick之后调用的函数内部获取get请求(未在代码中显示),然后更新状态并将数据作为props传递。在这种情况下,您每次都会在点击事件中发出新的获取请求。如果你不需要每次点击查看反应生命周期方法的新请求,特别是componentDidMount,它基本上是在安装了反应组件后执行的,那么你可以在那里做一个get请求并更新状态

componentDidMount: function() {
    $.get(this.props.source, function (data) {
       var log = $.parseJSON(data);
      this.setState( { content: log } );
   }.bind(this));
},

答案 3 :(得分:0)

我无法从您的代码中看到应该点击哪个组件来触发请求,但是就您所见,您应该从render()方法中取出请求。每次state / props更改时都会调用此方法,因此可能会使您的代码多次发出请求。

另一件事是你应该总是通过调用this.setState()方法改变你的状态,所以在你的情况下它会是_this.setState({ content: log })

现在,如果您在每次点击其他组件时更改name道具,您应该执行以下操作:

var ChangeLogData = React.createClass({

  getInitialState: function () {
    return {
        content: {},
    }
  },

  componentWillMount: function () {
    this.getLog(this.props.source);
  },

  componentWillReceiveProps: function (nextProps) {
     this.getLog(nextProps.source);
  },

  getLog: function (source) {
    var _this = this;

    $.get(source, function (data) {
        var log = $.parseJSON(data);
        _this.setState({
          content: log
        });

    }.bind(this));
  }


  render: function () {

    return (
        <div>
            {this.state.content[0]}
        </div>
     );
 }

首先,您可以提取流程以创建从render()方法到其自己的方法的请求调用,在本例中为getLog()。然后,使用React生命周期中的两个新方法,您可以在安装组件时以及每当来自父组件的新道具进入时调用getLog()