Amal Antony
Amal Antony

Reputation: 6837

Synchronising Async Redux actions for optimistic fetching

I'm building a product listing grid (like in an e-commerce site homepage) with Redux. The user can scroll infinitely and items are loaded from the server as they scroll. There is also a preemptive fetch during idle time, for the next batch of items.

I have modelled my redux actions (partially) as below:

During an intermediate LOAD_PRODUCTS, I can set a timeout to dispatch FETCH_PRODUCTS_REQUEST in order to preemptively fetch the set of items for the next batch.

However, I'm not entirely sure how to sync these actions on the initial page load (ie, when the ProductGrid component has mounted). I would ideally want to dispatch a FETCH_PRODUCTS_REQUEST on component mount and then wait for the FETCH_PRODUCTS_SUCCESS to happen and then dispatch LOAD_PRODUCTS.

Considering the one way data flow in Redux, I'm not clear on how I can make sure the initial FETCH_PRODUCTS_SUCCESS has been fired (ie, my store has preemptive data) before I can dispatch a LOAD_PRODUCTS to render this data onto the DOM.

I'm using the redux-saga library to dispatch async actions.

Any help would be appreciated!

Upvotes: 3

Views: 327

Answers (2)

Amal Antony
Amal Antony

Reputation: 6837

They key here was that the ProductGrid component was aware if the FETCH_PRODUCTS_REQUEST it was dispatching was an initialisation action (it happens inside componentDidMount). I added an isInitial flag as part of the action payload. The redux-saga middleware could then look at this value and then decide if a LOAD_PRODUCTS must be dispatched on receiving a FETCH_PRODUCTS_SUCCESS (this works because redux sagas are based on generators, so once the results are yielded by the async API, the saga can respond by sending the corresponding action(s) based on the action flag).

Upvotes: 0

Alp
Alp

Reputation: 29749

A naive approach would be to store the initialization state of your application.

For example:

function initialized(state = false, action) {
  switch (action.type) {
    case FETCH_PRODUCTS_SUCCESS:
      return true;
    default:
      return state;
  }
}

This will be false when initially loading the page and switch to true after the first successful product request.

Upvotes: 1

Related Questions