React组件在一次或多次点击中获取请求

React component get request being made in one or clicks late

本文关键字:请求 获取 一次 组件 React      更新时间:2023-09-26

这个有点难以解释,但基本上当单击一个组件时,我为另一个组件发出一些数据的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请求的数据。那么,我应该把事件处理程序放在哪里呢?

我认为问题是它没有被正确调用,因为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()

中的状态

你不应该在渲染方法中发出请求。您也不应该通过这个直接修改状态。而是使用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。这将导致组件重新呈现内容

  • 第一:get请求是异步的,所以当你得到响应时,DOM已经渲染好了。
  • 第二:永远不要在渲染方法中更新状态,如果它工作并且你没有得到一个错误消息,你很可能会创建一个无限循环,render => updateState => render => udpateState…

你有多个选项,你可以在onClick之后调用函数中的get请求(没有显示在你的代码中),然后更新状态和传递数据作为道具。在这种情况下,每次有click事件时,你都会发出一个新的get请求。如果你不需要每次点击都有一个新的get请求,看看react生命周期方法,特别是componentDidMount,它基本上是在react组件挂载后执行的,然后你可以在那里做一个get请求并更新状态

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

我无法从你的代码中看到应该点击哪个组件来触发请求,但就我所见,你应该从render()方法中取出请求。这个方法在每次状态/道具改变时被调用,所以它可能会让你的代码多次发出请求。

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

现在,如果每次单击另一个组件时都更改name prop,则应该这样做:
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(),以及每当从父组件获得新道具时。