Where to fetch initial state when using flummox (flux)?

434 views Asked by At

I'm trying to figure out where to load initial state, when using flummox, a flux library. I've see it done a few ways, but I'm curious if there's a recommended way to do it. Lets say you've got some todo items that you've saved in local storage or a database or something. Where would you fetch those and get them into your store's state?

I've seen it suggested to do the actual ajax query in react's componentDidMount, and trigger an action, passing in the result of the ajax to that action. That data would flow along into the store's state and back into the view as your initial state.

I've also seen it suggested to do the ajax inside of the action itself, which flummox seems to support pretty well with their async await support. I guess in this scenario you'd just trigger some get initial state action?

1

There are 1 answers

1
Anders Ekdahl On BEST ANSWER

You shouldn't load state from the server using an Ajax request directly in the components componentDidMount. The reason for this is that the purpose of Flux is to hide the nitty-gritty details of state fetching/management from the components. The Flux implementation should do that for you.

There are a lot of variations in the different Flux implementations, and there's really no right or wrong way.

Actions

There's one thing to think about when it comes to Actions and what you use them for. An action is supposed to be something that changes your application state. You can think of all actions combined as a bunch of transactions that was applied to your state. An action transitions your application data from one state to the next.

So if you were to loose all of the application state, you'd just apply all actions again in the right order, and you'd end up with the same state. So why is this important? Because it tells you what not to use actions for.

Some Flux implementations tends to mix actions (like "Update this todo item") and questions (like "Give me the todo item with id 2"). That can be convenient but it sort of blurs the definition of an action. And a question doesn't mutate state, it just reads from it.

Questions should instead be implemented as methods on Stores, like TodoStore.getItem(id) (which Flummox seems to favor).

Answer

So to answer your question: Even if getting the initial state is async and seems like a good fit for an action since Flummox has nice async support for them, I would load the initial state in the Store (probably using a simple Ajax request and then call setState on the store). This because it's the Store that owns the state and should know how to handle it. A component would then ask the Store for all items (using either Flummox's FluxComponent or fluxMixin). It would give an empty list for the first render, but as soon as the Ajax request completes the call to Store.setState() would trigger a re-render with the complete list.

Keeping all application state in memory

This turned out to be a wall of text, but I want to point one more thing out. Most Flux implementations out there (including Flummox) advocates that you keep your entire application state in memory in the stores. This is fine for a lot of cases, but if your application has a lot of data, that starts to break down. Not only because of memory use but also for things like searching where you don't want to iterate over thousands of objects to find a match, you want a database that handles that for you.

So for those cases, you probably want to store the state in IndexedDB or WebSQL instead and it becomes hard to integrate that with the Flux implementation that expects it to be a synchronous in-memory object.

If you don't expect to need that much application state on the client your fine using Flummox or any other Flux implementation, but it's something to keep in memory (no pun intended).