Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

When should ReactJS components make AJAX calls to update state from props?

I have a React component that displays information about an entity. The id of the entity is passed in via a property. The component starts an AJAX call in "componentDidMount" to fetch the entity and updates state when the call completes/fails.

This works fine except that the component does not fetch new data when the entity id changes (via props).

I have tried starting a call in "componentWillReceiveProps" but at that stage the component still has is old properties set. I would have to pass nextProps to the AJAX call method and that doesn't seem right.

What is the best/cleanest way to have a component asynchronously update its state in response to a property change?

like image 493
David Tinker Avatar asked Jun 08 '15 08:06

David Tinker


People also ask

Where in the component life cycle we should write AJAX call?

Where in the component lifecycle should I make an AJAX call? You should populate data with AJAX calls in the componentDidMount lifecycle method. This is so you can use setState to update your component when the data is retrieved.

What is the proper way to update the state in React?

To update our state, we use this. setState() and pass in an object. This object will get merged with the current state.

Why should states not be updated directly in React?

React will then look at the virtual DOM, it also has a copy of the old virtual DOM, that is why we shouldn't update the state directly, so we can have two different object references in memory, we have the old virtual DOM as well as the new virtual DOM.

Which method is used to update the state of the component in react JS?

setState() enqueues changes to the component state and tells React that this component and its children need to be re-rendered with the updated state. This is the primary method you use to update the user interface in response to event handlers and server responses.


1 Answers

I'm new to react as well, so the Flux architecture is a bit intimidating to me. I'm doing it exactly as you said, using componentWillMount to load initial data via AJAX, and then componentWillReceiveProps with nextProps to load new data again if/when props change:

var Table = React.createClass({
  getInitialState: function() {
    return { data: [] };
  },

  componentWillMount: function(){
    this.dataSource();
  },

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

  dataSource: function(props){
    props = props || this.props;

    return $.ajax({
      type: "get",
      dataType: 'json',
      url: '/products?page=' + props.page + "&pageSize=" + props.pageSize
    }).done(function(result){
      this.setState({ data: result });
    }.bind(this));
  },

  render: function() {
    return (
      <table className="table table-striped table-bordered">
        <Head />
        <Body data={this.state.data}/>
      </table>
    );
  }
});
like image 73
wnm Avatar answered Sep 22 '22 15:09

wnm