16

I have a react component, In which I am using a date picker. Based on value of Date selected I am sending an ajax request to fetch data. I am not using any frameworks like redux or flux.

export default class MyComponent extends Component {
    constructor(props) {
        super(props);
    }

    componentDidMount() {
        // Initial fetch request based on the default date
    }

    onDateSelectionChanged(fromDate, toDate) {
        this.setState({
            fromDate,
            toDate
        });
    }

    render() {
        return (
            <div className="row">
                <DateRangePicker callBackParent = {this.onDateSelectionChanged}/>
                {/* other stuff */}
            </div>
        );
    }
}

Now suppose I changed the date to another date. What is the best way to fetch the data again? should I fire request again inonDateSelectionChanged or is there any life-cycle method?

John Weisz
  • 30,137
  • 13
  • 89
  • 132
WitVault
  • 23,445
  • 19
  • 103
  • 133

4 Answers4

3

I strongly suggest to decouple the ajax logic from your component. Remeber that plain React was build only to simplify the rendering of the views and not for complex logic like Http calls.

Using Flux you can quickly create the infrastructure for handling both the UI rendering and any other logic for your app.

The complete tutorial is here but I will add a quick summary so that you could easily get started.

Add 4 classes that will be your infrastructure:

  1. YourComponentActions - this class will handle the "actions" that your component will fire. An action is actually an event that will be fired from your component to something that will perform the actual logic (point 4).
  2. SharedConstans - this class will hold the event names of your app.

  3. AppDispatcher - this class will manage the event handling of your app.

  4. YourComponentStore - this class will register to the action's event and handle the http call. Here is the logic of your component that is decoupled from the UI. After you receive a response from your ajax call you will fire another event from your store and your component will register to it and only then update the state.

It feels complex however from now on you will easily add any logic to your app while keeping it decoupled, readable and easy to maintain. Read more about Flux here.

Dennis Nerush
  • 5,473
  • 5
  • 25
  • 33
  • What about redux? Should I use flux or redux? It will be nice if you provide some comparison in your answser. thanks. – WitVault Mar 08 '16 at 06:46
  • 1
    Here you can find a great answer for your question http://stackoverflow.com/questions/32461229/why-use-redux-over-facebook-flux. I use flux and see no major advantage in moving to redux – Dennis Nerush Mar 08 '16 at 07:41
  • 1
    Redux doesn't specifically have any advantages over Flux, but it's a refinement of the ideas. The API is small enough that, if you stay within the bounds of "good practice" or "idiomatic code," you can enable some really powerful tools. Because all state changes are performed via actions and all state is immutable, Redux devtools can safely let you step forward and backward through applied actions, and with the right build tools, you can hot swap components and reducers without a full page refresh. – Carl Vitullo Mar 11 '16 at 01:34
2

You should fire another network request in onDateSelectionChanged, there's no lifecycle method for when state changes.

Technically speaking you could do some logic in componentWillUpdate (or worse, shouldComponentUpdate) to make a request when that state field changes and it would work, but you shouldn't. Both of those lifecycle methods have well defined purposes, making network requests would make your code less clear and harder to maintain.

Carl Vitullo
  • 853
  • 6
  • 15
  • sending network request on `onDateSelectionChanged` is last resort. I thought there should be some other way around to deal with it. – WitVault Mar 01 '16 at 08:50
  • "Where should network requests happen" is a question that Flux and Redux answer, but in just React you have to do it where the work is preformed. Might want to look at Flux/Redux pretty soon, that's where data flow issues are resolved. – Carl Vitullo Mar 01 '16 at 14:58
1

If you really insist on sending the request from your component method, than firing it in onDateSelectionChanged is definitely the way to go. As it responds to every Date change, it is naturally the only method capable of fulfilling your needs, and the lifecycle methods are not directly aware of the Date change nor the right place to do it. Implementing something like that in e.g. componentWillUpdate or componentDidUpdate can possibly lead to cyclic execution and that isn't something you want to face without a good reason.

Speaking of lifecycle methods, the only one explicitly recommended to fire requests is componentDidMount method, where you have a good opportunity to do some ajax initialization operations, as you can see in docs, but none of them is suitable for ordinary data fetching.

On the other hand, I suggest you really have a look at Flux, which is an architecture solving many issues, separation of concerns is on of them. Your problem here is that you tie your component to creation of Ajax requests, which doesn't promote reusability and makes your code harder to maintain. Think of components as tools to present content and capture users inputs, bothering with requests and response or processing and storing incoming data shouldn't be their concern (at least at larger scale).

You can of course separate your request creators to external functions, but if you tend to write React frontend, you will sooner or later face problems like handing props over many intermediary components or propagating events up through your component hierarchy, which is very tedious and messy without some kind of architecture, and Flux is the best solution for these issues and therefore number one technology to learn - if you mean it with React seriously.

Dan Macak
  • 16,109
  • 3
  • 26
  • 43
0
onDateSelectionChanged(fromDate, toDate) {
    var self = this; // we can not use this inside ajax success callback function
    this.setState({
        fromDate,
        toDate
    }, function() { // callback fires after state set
        // your ajax request goes here, let say we use jquery
        $.ajax({
           url: fetch_url, success: function(data) {
               // again we can setState after success, but be careful
               // we can not use "this" here instead we use "self"
               self.setState({
                   someState: data.someValue
               })
           }
        })
    });
}
Mike
  • 737
  • 1
  • 7
  • 11