DEV Community

Discussion on: Redux is half of a pattern (1/2)

Collapse
 
davidkpiano profile image
David K. 🎹

I don't see why Redux should need to contain any async logic at all. Put it elsewhere.

This is the main problem I'm trying to highlight. Fragmented logic because of an incomplete pattern.

Collapse
 
oliverradini profile image
OliverRadini

Sure - but if Redux took a more holistic approach, and went so far as to implement state machines, then it'd be a different library. There are options out there which do give you state machines in javascript, for instance XState - which you develop (as an aside, I think it'd be better if you state quite explicitly that you're the developer of that library, for the sake of full disclosure).

In the example you give of Reddit's loading state, we might equally view whether or not there were no results as an item of derived state. It can be derived from two items of required state; the set of results, and the loading state of the application. Something like:

const hasNoResults = ({ results, loading }) => !loading
  && results.length === 0;

Not saying this is a better approach, just a different one, and a different solution to the same problem. Different perspectives will yield different results and it's hard to give very clear guidance as to which is better in all situations, and I think that calling Redux half a pattern is a little misleading. It's half of the pattern you decided to compare it against, or, it isn't a pattern which could be called state machines.

Thread Thread
 
davidkpiano profile image
David K. 🎹

as an aside, I think it'd be better if you state quite explicitly that you're the developer of that library, for the sake of full disclosure

I didn't want to do this because I just wanted to talk about Redux and state machines, instead of comparing/promoting my library. I didn't think that would be fair.

Not saying this is a better approach, just a different one, and a different solution to the same problem.

Of course! You can definitely write your logic like this, without explicit state machines, and cover all the edge cases, and have it work just as well as an explicit state machine approach. It just becomes much harder to "reason about" and understand how the app flows from a higher level. But if you don't care about that (and you just want to ship stuff the way you know best), then that's fine.

It's half of the pattern you decided to compare it against, or, it isn't a pattern which could be called state machines.

No, it's half of a pattern because it provides lightly opinionated "scaffolding" (atomic global state, reducers are pure functions with no constraints except for purity, side-effects via middleware somehow) but the other half of the pattern is what the user needs to implement themselves. They need to "fill in the blanks" and that leads to them constantly half-inventing state machines, whether they know it or not.

Like I said, the comparison against state machines isn't an arbitrary choice. Our UIs are state machines.

Thread Thread
 
oliverradini profile image
OliverRadini

I do still think it's relevant to mention that you've developed that library. Not to say that it makes you biased; it makes you informed on state machines and the strengths/weaknesses of that pattern.

Anything that's half a pattern could be considered a whole of some other pattern. The boundaries between patterns are completely arbitrary and we can draw the lines where we like.

I wholly disagree that using derived state is less reasonable than state machines. The two aren't mutually exclusive in any case, but both patterns have their supporters and theory, both patterns are likely equally able to be reasoned about. Indeed both are likely to be little more than constraints which can be applied to state management, and it's quite possible that both make an application's state a more reasonable proposition.

Thread Thread
 
davidkpiano profile image
David K. 🎹

I wholly disagree that using derived state is less reasonable than state machines.

But it is! The proof is that derived state can determine "what state are we in", and finite state machines can also determine "now that we're in this state, what can happen next?" That part is valuable information, and very hard to determine without some sort of abstract model.

Thread Thread
 
oliverradini profile image
OliverRadini

Indeed you're correct; though to reiterate what I said in the last reply, both are restrictions we can apply onto state which are likely to make it more reasonable. I don't think they're anything like mutually exclusive.

I had meant for derived state to be little more of an example of a different pattern which you could measure Redux and/or state machines against. My point was intended to be that these types of comparisons depend on the reference points of those comparisons; Redux is 100% of one pattern and 50% of another, and 0-99% of yet more patterns.