Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Flux: How to make an action wait for a store?

I'm tying myself in knots with a React problem which I'm sure can't be as difficult as it seems to me right now.

I'm building a single page app against a RESTful server API that returns resources, together with links that describe what can be done with that resource. And I'm trying to ensure that my client's ajax calls only use URLs retrieved from the server in this way. So, for example, my LoggedInSessionStore contains the URL that allows me to fetch the list of all public documents, say.

The problem I have is how to manage the dependencies between actions and stores. For example, when the action to fetch all public documents fires, it needs to get its URL from the LoggedInSessionStore. But that store may not yet have been populated yet; so the action must not fire until a previous action (fetch the login session) has completed.

So, I want an action that can fetch server data using a URL that is stored in a store. What is the accepted way to ensure that the action cannot fire until that store has been populated?

like image 913
kevinrutherford Avatar asked Oct 20 '22 11:10

kevinrutherford


1 Answers

TL;DR Don't store your URLs in your Stores. Let your actions handle API calls.

In general when using Flux your actions should not know about your stores. Data in a Flux application is meant to flow in one direction:

Components --> Actions --> Dispatcher --> Stores --> Components

Your React components create actions, which are then dispatched by the Dispatcher to your stores. Stores will be notified of the actions via their registered callback and will update themselves accordingly. Components will listen for stores to update themselves and they will update their own state accordingly. Thus the circle is completed.

The point being: Actions should not depend on stores

What I would suggest is that you move all your API logic into actions. This includes the URLs for your API. This is a fairly common pattern in Flux applications:

  1. A component triggers a fetch action on componentDidMount. Displays loading spinner since it does not yet have the data it needs to render.
  2. The fetch action makes an AJAX call to fetch data from the server.
  3. When the data comes back from the server, the action dispatches it as a payload
  4. A store sees the payload and sets its internal state based on the fetched data
  5. The component sees that the store has been updated, and updates its own state accordingly. This causes it to render the app instead of just a loading spinner.

An alternative option is have your fetch logic inside your stores, including the AJAX request code. I find the former easier to reason about (stores know nothing, they just react to data when its available) but it's up to you how you want to implement it. Just make sure that the API fetching logic is in one place only, not split between Actions and Stores.

This thread may also be helpful: Should flux stores, or actions (or both) touch external services?

like image 180
ian Avatar answered Oct 22 '22 01:10

ian