question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

[discussion] how can we improve state management?

See original GitHub issue

As I’m working on a real-world application I’m noticing there’s friction using stores, and I’m becoming unsure if namspacing is the best construct available.

Nested data structures are hard to model and use. Say we’re building a giant form website with multiple forms on it, we might have the fields of “form”, “questions” and “fields”. We might perhaps want to track the state of these separately; as having a single blob make up 90% of our application doesn’t quite feel right. “form”, “questions” and “fields” all have their own little bits of logic and what not.

rdbms

An approach we could do here is have each of these be expressed in a relation of “one-to-one”, “many-to-many”, “many-to-one” (oneToOne, many, fk in RDBMS-speak respectively). This would allow us to define the fields between the respective items. And flatten them in our representation, making it easier to view and reason about. There’s prior art in redux-orm and querying a redux store

The redux docs state the following:

In a more complex app, you’re going to want different entities to reference each other. We suggest that you keep your state as normalized as possible, without any nesting. Keep every entity in an object stored with an ID as a key, and use IDs to reference it from other entities, or lists. Think of the app’s state as a database.

There’s also reselect which creates higher level views on top of normalized data, and updates to match. I like this idea because it matches the idea of how I think about data.

namespaces

But all of this raises the question: how useful are namespaces at this point? If our data is completely intertwined, and method calls on values rely on all data being available (e.g. “how many fields are completed on this form?”), then what’s the point of having namespaces? In a sense we’d be implementing namespaces as a way to interact with our flat data.

Some considerations we might need to make regarding namespaces:

  • is it even possible to move namespacing to userland?
  • how would namespaced actions work? - could we override this using the new wrappers API from 3.3.0?
  • what do we lose if we move namespacing to userland?
  • what do we gain if we move namespacing to userland?
  • how would it affect our codebase?

I suspect it’s definitely possible, and would shrink the codebase significantly

  • but we should check our facts first tho. We could totally test userland namespace packages on top of existing choo if we just don’t namespace our models. Probably it would need to use a different character internally to namespace when sending actions, but that’s about it (e.g. don’t use : as it’s special right now).

graph

I feel the endgame of RDBMS and selectors is to implement a graph structure where relationships can be used to query data (e.g. “give me all questions of form foo”, “give me all fields of question bar”).

Now what I wonder is if we could leapfrog over the implementation details, of RDBMS and selectors and implement a graph structure directly on top of a single object. This would be similar in spirit to @mcollina’s levelgraph.

Now my knowledge on databases isn’t great, and I don’t have any prior experience implementing databases (relational, graph or otherwise) so any input here would be grand.

edit: for those unfamiliar with graph databases, I’ve found a great article explaining the differences between graph and RDBMS databases: https://neo4j.com/developer/graph-db-vs-rdbms/. Especially the chart showing the same data expressed in the different paradigms is interesting I found:

relational

relational architecture example

graph

graph architecture example

wrapping up

I’d be keen to hear people’s thoughts on this. Like I said this post is coming from seeing choo’s existing abstractions break down at a larger scale, and the desire to do better. Thanks for making it this far down the post; let me know what you think ✌️

Related issues

See Also

Issue Analytics

  • State:closed
  • Created 7 years ago
  • Reactions:1
  • Comments:31 (10 by maintainers)

github_iconTop GitHub Comments

6reactions
yoshuawuytscommented, Sep 24, 2016

Heya, thanks for the replies everyone! - Even though I’ve been a bit silent, I’ve read it all, and y’all put out some great stuff. What I’m thinking right now is:

  • yeah keep choo batteries included, that’s kinda the point of the framework
  • make sure we can use plugins to experiment with mad sciency resolving stuff (including perhaps pattern matching? - I’ve seen demos of bloomrun, it’s very very cool)
  • add first class array support for model.state so they become less unwieldy

How does that sound?

ps. Also docs everywhere; we’re using selectors on a real world project rn and it seems to work alright enough - just a few tweaks could probably make it better C:

6reactions
ajoslincommented, Sep 10, 2016

I’ve encountered the same problem and have had the same doubts about Choo’s state management at scale.

Once you have hundreds of components and hundreds of models, it will just not work to have everything global and have string namespaces for everything.

All I can say is Mercury, despite its flaws, has the best model for state management I’ve seen in JS. In my opinion, the best three things about its state story are:

  1. Extremely strict rules for how you mutate state
  2. Strict separation and modularization of state atoms (each Mercury component is basically an app)
  3. Very powerful way to react to and watch state changes via Observ API

Mercury has a lot of flaws in terms of understandability, but we should learn from its good parts (and Elm/Om).

I’d caution against copying Redux too much… It falls apart at scale in similar ways to Choo’s current state system.

Generally, I agree with the idea behind @mantoni’s comments – one of the biggest problems with the current system is that “everything is global.” If we moved to smaller apps that can require() and compose each other, we can approach a much better system.

I will try to elaborate with more specifics later. Let’s keep this discussion going.

Read more comments on GitHub >

github_iconTop Results From Across the Web

What is State-Management and Why You Should Learn It?
State -Management is the implementation of a Design Pattern, with the help of this design pattern we can synchronize the state of the...
Read more >
State Management
Now that you understand the client-based state management techniques let's explore the server-based state management techniques. We'll begin ...
Read more >
React State and How to Manage It
I 'll like to talk about how to understand state in a way that helps you make more informed decisions about managing it....
Read more >
React: When To Use A State-Management Solution?
An introduction to state management with a concise guide on when and how to implement it.
Read more >
3 Effective Ways To Implement State Management In Next.js
State management plays a vital role in any modern web application. The reason is that state helps to determine what data is rendered...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found