admin管理员组

文章数量:1240587

I have the following code:

var Panel = React.createClass({

  getInitialState: function () {
    return {
      user_id: null,
      blogs: null,
      error: false,
      error_code: '',
      error_code: ''
    };
  },

  shouldComponentUpdate: function(nextProps, nextState) {
    if (nextState.error !== this.state.error ||
        nextState.blogs !== this.state.blogs ||
        nextState.error_code !== this.state.error_code
      ) {
      return true;
    }
  },

  ponentDidMount: function() {
    var self = this;
    var pollingInterval = setInterval(function() {
      $.get(self.props.source, function(result) {
        if (self.isMounted()) {
          self.setState({
            error: false,
            error_code: '',
            error_message: '',
            blogs: result.user.blogs,
            user_id: result.user.id
          });
        }
      }.bind(self)).fail(function(response) {
        self.setState({
          error: true,
          error_code: response.status,
          error_message: response.statusText
        });
      }.bind(self));
    }, 1000);
  },

  render: function() { ... }

});

The important part to focus on is the ponentDidMount This will fetch every second, regardless if there is an error or not. The render function, assuming theres an error, will display the appropriate method. So for all intense and purpose, this code does exactly what I want it to do, it fetches, if it fails, it fetches again until it succeeds.

But I need to make some changes, and this is where I am lost. I want to say: Fetch once, pass or fail - it doesn't matter. THEN every 15 seconds after that initial fetch, try again - regardless of pass or fail

I would normally spin up a backbone collection and router along with a poll helper to do all this, but in this specific case there is no need for the extra overhead. So thats where I am stumped. How do I acplish what I am trying to achieve?

I have the following code:

var Panel = React.createClass({

  getInitialState: function () {
    return {
      user_id: null,
      blogs: null,
      error: false,
      error_code: '',
      error_code: ''
    };
  },

  shouldComponentUpdate: function(nextProps, nextState) {
    if (nextState.error !== this.state.error ||
        nextState.blogs !== this.state.blogs ||
        nextState.error_code !== this.state.error_code
      ) {
      return true;
    }
  },

  ponentDidMount: function() {
    var self = this;
    var pollingInterval = setInterval(function() {
      $.get(self.props.source, function(result) {
        if (self.isMounted()) {
          self.setState({
            error: false,
            error_code: '',
            error_message: '',
            blogs: result.user.blogs,
            user_id: result.user.id
          });
        }
      }.bind(self)).fail(function(response) {
        self.setState({
          error: true,
          error_code: response.status,
          error_message: response.statusText
        });
      }.bind(self));
    }, 1000);
  },

  render: function() { ... }

});

The important part to focus on is the ponentDidMount This will fetch every second, regardless if there is an error or not. The render function, assuming theres an error, will display the appropriate method. So for all intense and purpose, this code does exactly what I want it to do, it fetches, if it fails, it fetches again until it succeeds.

But I need to make some changes, and this is where I am lost. I want to say: Fetch once, pass or fail - it doesn't matter. THEN every 15 seconds after that initial fetch, try again - regardless of pass or fail

I would normally spin up a backbone collection and router along with a poll helper to do all this, but in this specific case there is no need for the extra overhead. So thats where I am stumped. How do I acplish what I am trying to achieve?

Share Improve this question asked Feb 27, 2015 at 17:39 TheWebsTheWebs 12.9k32 gold badges114 silver badges220 bronze badges 3
  • Can't you just add a method that after mounting, is called every 15 seconds? Just move the code that you have in the body of setInterval into a function, and in the ponentDidMount, start it. And repeat. You'd want to check isMounted() potentially. – WiredPrairie Commented Feb 27, 2015 at 17:51
  • I was thinking that, but I didnt know if that would work because I believe ponentDidMount is only called once after render? unless im a crack head? – TheWebs Commented Feb 27, 2015 at 18:01
  • (I'm not sure about drug habits ...:-) ). Yes, ponentDidMount only is executed once: facebook.github.io/react/docs/ponent-specs.html. So, you could start it there. You'd want to disable the timer when the ponent is unmounted. – WiredPrairie Commented Feb 27, 2015 at 18:39
Add a ment  | 

1 Answer 1

Reset to default 14

You should be able to just refactor your code a bit to be able to call your polling function a few different ways (like manually for example and then at a specified interval):

ponentDidMount: function() {
  this.startPolling();
},

ponentWillUnmount: function() {
    if (this._timer) {
      clearInterval(this._timer);
      this._timer = null;
    }
},

startPolling: function() {
    var self = this;
    setTimeout(function() {
      if (!self.isMounted()) { return; } // abandon 
      self.poll(); // do it once and then start it up ...
      self._timer = setInterval(self.poll.bind(self), 15000);
    }, 1000);
},

poll: function() {
    var self = this;
    $.get(self.props.source, function(result) {
      if (self.isMounted()) {
        self.setState({
          error: false,
          error_code: '',
          error_message: '',
          blogs: result.user.blogs,
          user_id: result.user.id
        });
      }
    }).fail(function(response) {
      self.setState({
        error: true,
        error_code: response.status,
        error_message: response.statusText
      });
    });
}

本文标签: javascriptDo something oncethen every 15 seconds in react jsStack Overflow