Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why use one store per entity in the flux application architecture?

I am using reactjs and the flux architecture in a project I'm working on. I am a bit puzzled by how to break up nested data correctly into stores and why I should split up my data into multiple stores.

To explain the problem I'll use this example:

Imagine a Todo application where you have Projects. Each project has tasks and each task can have notes.

The application uses a REST api to retrieve the data, returning the following response:

{
    projects: [
        { 
            id: 1, 
            name: "Action Required",
            tasks: [
                {
                    id: 1,
                    name: "Go grocery shopping",
                    notes: [
                        {
                            id: 1,
                            name: "Check shop 1"
                        },
                        {
                            id: 2,
                            name: "Also check shop 2"
                        }
                    ]
                }
            ]
        },
    ]
}

The fictive application's interface displays a list of projects on the left and when you select a project, that project becomes active and its tasks are displayed on the right. When you click a task you can see its notes in a popup.

What I would do is use 1 single store, the "Project Store". An action does the request to the server, fetches the data and instructs the store to fill itself with the new data. The store internally saves this tree of entities (Projects -> Tasks -> Notes).

To be able to show and hide tasks based on which project is selected I'd also keep a variable in the store, "activeProjectId". Based on that the view can get the active project, its tasks and render them.

Problem solved.

However: after searching a bit online to see if this is a good solution I see a lot of people stating that you should use a separate store per entity.

This would mean: A ProjectStore, TaskStore and NoteStore. To be able to manage associations I would possibly also need a "TasksByProjectStore" and a "NotesByTaskStore".

Can someone please explain why this would be better? The only thing I see is a lot of overhead in managing the stores and the data flow.

like image 577
Geoffrey De Vylder Avatar asked Oct 13 '15 15:10

Geoffrey De Vylder


1 Answers

There are pro's and cons to use one store or different stores. Some implementations of flux specifically favour one store to rule them all, so to speak, while others also facilitate multiple stores.

Whether one store or multiple stores suit your needs, depend on a) what your app does, and b) which future developments or changes you expect. In a nutshell:

  • One store is better if your key concern is the dependencies between your nested entities. And if you are less worried about dependencies between single entity relation between server-store-component. One store is great if e.g. you want to manage stats on project level about underlying tasks and notes. Many parent-child-like relationships and all-in-one data fetching form server favour one store solution.
  • Multiple stores better if your key concern is dependencies between single entity connections between server-store-component. Weak entity-to-entity relationships and independent single entity server fetches and updates favour multiple stores.

In your case: my bet would be that one store is better. You have evident parent-child relationship, and get all project data at once from server.

The somewhat longer answer:

One store:

  • Great to minimize overhead of managing multiple stores.
  • It works well if your top view component is the only stateful component, and gets all data from the store, and distributes details to stateless children.
  • However, the need to manage dependencies between your entities does not simply go away: instead of managing them between different stores, you need to manage them inside the single store. Which therefore gets bigger (more lines of code).
  • Also, in a typical flux setup, each store emits a single 'I have changed' event, and leaves it up to the component(s) to figure out what changed and if they need top re-render. So if you have many nested entities, and one of the entities receives many updates from the server, then your superstore emits many changes, which might trigger a lot of unnecessary updates of the entire structure and all components. Flux-react can handle a lot, and the detail-changed-update-everything is what it handles well, but it may not suit everyones needs (I had to abandon this approach when it screwed up my transitions between states in one project).

Multiple stores:

  • more overhead, yes, but for some projects you get returns as well
  • if you have a close coupling between server data and components, with the flux store in between, it is easier to separate concerns in separate stores
  • if e.g. you are expecting many changes and updates to your notes data structure, than it is easier to have a stateful component for notes, that listens to the notes store, which in turn handles notes data updates from the server. When processing changes in your notes structure, you can focus on notes store only, without figuring out how notes are handled inside some big superstore.
like image 73
wintvelt Avatar answered Oct 12 '22 01:10

wintvelt