We're planting a tree for every job application! Click here to learn more

Redesigning Redux

Shawn McKay

14 Mar 2018

6 min read

Redesigning Redux
  • Redux

Redesigning Redux

Shouldn’t state management be a solved problem by now? Intuitively, developers seem to know a hidden truth: state management seems harder than it needs to be. In this article, we’ll try to answer some questions you’ve probably been asking yourself:

Let’s take a look at our options when using a component based view framework/library like React:

Redesigning Redux # 1.png

1. Component State

State that exists inside of a single component. In React, think state updated with setState.

2. Relative State

State passed from a parent to a child. In React, think props passed as properties on a child component.

3. Provided State

State held in a root provider, and accessed by a consumer somewhere down the component tree, regardless of proximity. In React, think of the context API.

A lot of state belongs in the view, as it reflects the UI. But what about all the other code that reflects your underlying data and logic?

Putting everything inside of views can lead to a poor separation of concerns: it ties you to a JavaScript view library, it makes code harder to test, and perhaps the greatest annoyance: you have to constantly think and readjust where you store your state.

State management is complicated by the fact that designs change and it’s often hard to tell which components will need which state. The simplest choice is to just provide all of the state from the root component, at which point you’re probably better off just going with next option.

4. External State

State can be moved outside of your view library. The library can then “connect” using the provider/consumer pattern to keep in sync.

Perhaps the most popular state management library is Redux. Over the past two years it has grown massively in popularity. So why so much love for a simple library?

Is Redux more performant? No. In fact, it gets slightly slower with each new action that must be handled.

Is Redux simpler? Certainly not.

Simple would be pure JavaScript:

Redesigning Redux # 2.JPG

So why isn’t everyone just using global.state = {}?

Why Redux?

Under the hood, Redux really is just the same as TJ’s root object — only wrapped within a pipeline of utilities.

Redesigning Redux # 4.JPG

In Redux, you can’t directly modify the state. There is only one way in: dispatch an action into the pipeline that eventually updates the state.

There are two sets of listeners along the pipeline: middleware & subscriptions. Middleware are functions that can listen to actions passed in, enabling tools such as a “logger”, “devtools”, or a “syncWithServer” listener. Subscriptions are the functions used to broadcast these state changes.

Finally, reducers update functions that can break down state changes into smaller, more modular and manageable chunks.

Redux may actually be simpler for development than having a global object as your state.

Think of Redux as a global object with pre/post update hooks, and a simplified way of “reducing” the next state.

But isn’t Redux too complicated?

Yes. There are several undeniable signs of an API in need of improvement; these can be summed up with the following equation:

Redesigning Redux # 7.png

Consider time_saved to represent the time you may have spent developing your own solution, while time_invested equates to the hours invested in reading documentation, taking tutorials, and researching unfamiliar concepts.

Redux is essentially a simple and small library with a steep learning curve. For every developer that has overcome and benefitted from Redux as a deep dive into functional programming, there has been another potential developer lost and thinking “this isn’t for me, I’m going back to jQuery”.

You don’t need to understand what a “comonad” is to use jQuery, and you shouldn’t necessarily need to comprehend functional composition to handle state management.

The purpose of any library is to make something more complicated seem simple through abstraction.

To be clear my intent is not to troll Dan Abramov. Redux became too popular, too early in its infancy.

You can’t. But you can provide amazing support through extensive docs, educational videos and community outreach. Dan Abramov for the win here.

Or perhaps there’s another way.

Redesigning Redux

I would argue that Redux deserves a rewrite. And I come armed with 7 areas that should be improved.

Setup

Let’s take a look at a basic setup from the real world Redux example on the left.

Redesigning Redux # 8.png

Many developers have paused here, after just the first step, staring blankly into the abyss. What’s a thunk? Compose? Can a function even do that?

Consider if Redux were based on configuration over composition. Setup might look more like the example on the right.

Simplified Reducers

Reducers in Redux could use a switch away from the unnecessarily verbose switch statements we’ve grown used to.

Redesigning Redux # 9.png

Assuming that a reducer is matching on action type, we can invert the params so that each reducer is a pure function accepting state and an action. Maybe even simpler, we could standardize actions and pass in only state and a payload.

Async/Await over Thunks

Thunks are commonly used for creating async actions in Redux. In many ways, the way a thunk works seems more like a clever hack than an officially recommended solution. Follow me here:

Really? Is it not bad practice for a simple action to be a dynamically typed as an object, or function, or even a Promise?

Redesigning Redux # 10.png

Like the example on the right, can’t we just async/await?

Two Kinds of Actions

Making a distinction between these two types of actions would be more helpful and less confusing that the above usage with “thunks”.

No More Action Types As Variables

Why is it standard practice to treat action creators and reducers differently? Can one exist without the other? Does changing one not effect the other?

Redux may actually be simpler for development than having a global object as your state.

const ACTION_ONE = 'ACTION_ONE' is a redundant side effect of the separation of action creators and reducers. Treat the two as one, and there is no more need for large files of exported type strings.

Reducers That Are Action Creators

Grouping the elements of Redux by their use, and you’re likely to come up with a simpler pattern.

Redesigning Redux # 12.png

Its possible to automagically determine the action creator from the reducer. After all, in this scenario the reducer can become the action creator.

Use a basic naming convention, and the following is predictable:

Redesigning REDUX # 123.png

Now from count.increment we can generate the action creator from just the reducer.

Good News: We Can Have A Better Redux

These pain points are the reason we created Rematch.

Redesigning REDUX # 13.png

Rematch is a wrapper around Redux that provides a simpler API, without losing any of the configurability.

RR # 14.png

See a complete Rematch example below:

RR # 15.png

I’ve been using Rematch in production for the past few months. As a testimonial, I’ll say:

I have never spent so little time thinking about state management.

Redux isn’t going away, and shouldn’t. Embrace the simple patterns behind Redux with less of learning curve, less boilerplate and less cognitive overhead.

Try Rematch, see if you don’t love it. And give us a star to let others know you do.

Did you like this article?

See other articles by

Related jobs

Title

The company

title

Remote

Title

The company

title

Remote

Title

The company

title

Remote

Title

The company

title

Remote

Related articles

JavaScript Functional Style Made Simple

JavaScript Functional Style Made Simple

Daniel Boros

12 Sep 2021

JavaScript Functional Style Made Simple

JavaScript Functional Style Made Simple

Daniel Boros

12 Sep 2021

CareersCompaniesSitemapFunctional WorksBlockchain WorksJavaScript WorksAI WorksGolang WorksJava WorksPython WorksRemote Works
email iconhello@works-hub.comUK flag

Ground Floor, Verse Building, 18 Brunswick Place, London, N1 6DZ

US flag

108 E 16th Street, New York, NY 10003

Subscribe to our newsletter

Join over 111,000 others and get access to exclusive content, job opportunities and more!

© 2021 WorksHub

Privacy PolicyDeveloped by WorksHub