Redux Redone: Learning Redux by recreating it from scratch
Tags: react, redux, javascript, opensource
Published: 2019-10-23 17:16:38

![Photo by [Markus Spiske](https://unsplash.com/@markusspiske?utm_source=medium&utm_medium=referral) on [Unsplash](https://unsplash.com?utm_source=medium&utm_medium=referral)](https://cdn-images-1.medium.com/max/11520/0*8lMhSW9Mpl_zPfxM)

I’ve been working with React for quite some time now. Anybody who’s done that, has faced the issue of managing global state in their app and given its popularity, probably ended up using Redux.

When I encountered Redux for the first time, I ran away in horror. The sheer number of new concepts that I had to learn, was just overwhelming. I just wanted to share some state around 😕. I tried out a bunch of other solutions

* MobX

* Unstated

* Context API

They’re all great (relatively speaking). However Redux still reigns supreme somehow. I couldn’t just keep avoiding it. So I eventually decided that something had to be done. I decided to learn Redux by making it my own. No, I wasn’t planning on forking the Redux repository and making contributions to it. I don’t have anywhere near the amount of grey matter required to do that. I decided to learn Redux by making my own measly state management library. Following were my aims

* Learn Redux (The good and bad parts)

* Recreate it without the bad parts, while still keeping the good parts around

## The Bad Parts

Redux is overly verbose. It fragments the hell out of your codebase. Separation of concerns is one thing but Redux shreds your apps to bits. There is no cohesion. Its hell to understand the flow in a Redux app. To be able to make an asynchronous update to your state (for e.g. as a result of an API call), you need to resort to things like Thunks, Sagas, Epics. Have to create separate Actions (and Action Creators) and Reducers for handling the in progress, success and failure states spread across multiple files. Furthermore, It encourages you to have a single global store. You can create separate reducers, but conceptually a reducer shouldn’t be responsible for this separation. To summarize, following is what I despise in Redux

* Too much to learn

* Code fragmentation

* No built in way to handle asynchronous flow

* Single global store

## The Good Parts

Redux is (extremely) popular and prevalent. You just can’t avoid it. Besides this, the only other redeeming quality I could find was its architecture. Its based on the Flux pattern
>  Flux is a pattern for managing data flow in your application. The most important concept is that data flows in one direction.

Flux makes a lot of sense. It basically ensures that the all state changes in your app go through a strict pipeline, in theory making debugging easier. Read up on it [here](https://www.cabotsolutions.com/2017/01/detailed-study-flux-react-js-application-architecture). It has a ‘few’ core concepts

* **Actions**: These represent the operations that can be applied to the state usually implemented as plain objects describing the ‘type’ of the action and any associated data.

* **Dispatcher**: Its a singleton that routes actions to stores

* **Store(s)**: Its where your data lives. In Flux, the Stores are also responsible for responding to actions by changing their internal state.

* **Views**: This is where React usually comes in. React components subscribe to the Stores and listen for change events, so they can be re-rendered.

## A Better Flux Implementation

So, basically what I wanted to do at this point was to make a ‘*better*’ (than Redux, IMHO) implementation of the Flux architecture (and learn Redux in the process 😖). And I did it with [react-3ducks](https://github.com/smakazmi/react-3ducks).

{% github smakazmi/react-3ducks %}

Its not a joke, It just sounds like one 😄.

What I discovered was that ‘Redux’ took the whole Flux pattern too literally. In my opinion, Redux doesn’t do as much as it could to make our lives easier. Let’s see an example of how I think it could be done. Introducing the StateStore class
>  **StateStore**: A class that accepts some initial state in its constructor and provides a method called **setState** that accepts and applies partial changes to the said state. Sounds familiar so far ? This is exactly how internal state works in React Components. **setState** also fires events to allow subscribed components to re-render.

**StateStore** is basically the combined implementation of the Store, Action and Dispatcher concepts. An implementation of **StateStore** could be as follows

 {% gist https://gist.github.com/smakazmi/8557be556948d13cc996db998b451984 %}

There’s no boilerplate here. Just a class that has some methods, which interact with the state. **StateStore** takes care of informing any concerned components of the changes. Notice the **addRandomTodo** method that fetches a random quote via **axios** and adds it as a todo. Just a plain and simple async javascript method. No juggling required with multiple Actions, Actions Creators, Reducers, Thunks, Sagas, Epics etc.

But we need a mechanism for components to subscribe to the state as well. That’s where the **container** higher order component comes in

{% gist https://gist.github.com/smakazmi/a9248c064083d4d6bf798e14e3d05362 %}

This is similar to the **connect** helper found in react-redux. The first parameter is obviously the component being wrapped. The second optional parameter is used to map container props to store methods or state. If its not provided, all the store instance(s) are passed as props to the wrapped component. Not to worry though, in either case, it makes clever use of [ES6 proxies](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Proxy) to only subscribe to the state that’s used in the component’s rendering. Its pretty neat.

We created a store, that we then initialized with some state and exported. The we created a container component that subscribed to the store. We still need to provide the store instances to our app somehow. That’s done through another higher order component called **root**.

{% gist https://gist.github.com/smakazmi/b9e70b03181a9ec4184be6b88dc106b8 %}

The **root** higher order component basically makes the stores available to any child container components in the hierarchy.

See this example in action [here](https://stackblitz.com/github/smakazmi/react-3ducks/tree/master/examples/todos)

That’s the entirety of the API that you need to know to use [react-3ducks](https://github.com/smakazmi/react-3ducks).

* StateStore

* container

* root

Check it out and let me know your feedback. Contributions to the project are very welcome.

I’ll probably do another post on the internals of the library later.