paint-brush
Introducing slim-redux-react — a faster, more concise way of building redux based react appsby@aGuyNamedJonas
2,431 reads
2,431 reads

Introducing slim-redux-react — a faster, more concise way of building redux based react apps

by Jonas PeeckApril 11th, 2017
Read on Terminal Reader
Read this story w/o Javascript
tldt arrow

Too Long; Didn't Read

Time for a somewhat embarrassing truth: I love the simplicity of <a href="https://hackernoon.com/tagged/redux" target="_blank">redux</a> on a theoretical level, yet somehow production setups of redux often confuse the hell out of me.

People Mentioned

Mention Thumbnail

Companies Mentioned

Mention Thumbnail
Mention Thumbnail
featured image - Introducing slim-redux-react — a faster, more concise way of building redux based react apps
Jonas Peeck HackerNoon profile picture

Bundle your action and reducer definitions into change triggers, and give your components quick access to the state through subscriptions

🢂Don’t want to read boring text? You’re in luck! Watch the demo on Youtube: (45 min)

Time for a somewhat embarrassing truth: I love the simplicity of redux on a theoretical level, yet somehow production setups of redux often confuse the hell out of me.

I think the main point which throws me off and makes it hard for me personally to work with redux production code is the huge amount of overhead that is usually required to build and maintain a working redux system.

Take the official React Redux TodoMVC example: The simple act of adding a todo to the store through a component involves 6 separate files:

  1. ADD_TODO Action constant in constants/ActionTypes.js
  2. addTodo() Action creator function in actions/index.js
  3. Reducer in reducers/todos.js
  4. Root reducer in reducers/index.js
  5. Container Component in containers/App.js
  6. Actual visual component allowing users to add a todo in components/Header.js

(Take a look at this gist I created highlighting the code used from the files)



What’s so frustrating to me about this is that all I want to accomplish are two very simple tasks:#1 Have my visual component call a function with some data that adds the todo item to the store#2 Give that whole process a name — more specifically: Have a ADD_TODO action appear in my redux-devtools so I know what’s going on

Design goals of slim-redux-react

So to get around these issues, I create slim-redux & slim-redux-react with three specific design goals and redux’s basic principles in mind:

Design goal #1: Less boilerplate

While reading through the three core principles behind redux, I realized that it is possible to re-package how we work with redux, without compromising its original design goals.

slim-redux reduces boilerplate by letting you bundle action and reducer definitions into change triggers (that have optional payload validation).

slim-redux-react gives your react components quick access to the store through subscriptions and and lets them modify the state through change triggers.

Design goal #2: Faster to code

Especially for small state changes the regular redux-react approach takes a long time. I found myself having to setup quite a bit of code to what came down to changing a property in the state or adding an element to an array.

slim-redux and slim-redux-react were built in a way that makes defining store interactions and passing them to react components very fast and slim.

Design goal #3: Easier to reason about code

By bundling actions and reducers into change triggers (that have optional payload validation), everything you need to know about a specific store interaction lives in one file, inside a single API call.

When connecting slim-redux to your react components, a single API call lets you provide change triggers and store-subscriptions to your visual components which has a low enough footprint to export your visual- and your container component from the same file (most of the time)

Demo

A demo says more than a thousand words, so let’s take a look at a counter app built with slim-redux-react:

This code is the condensed version of the slim-redux-react counter example. You can just download it, npm install it and then npm start it :)

(you can also open up the gist in a new tab, to follow along)

Step #1: Create the slim-redux store

As with your regular redux code, we first of all need to create a store. Slim-redux is a good sport and happily co-exists next to your already existing redux code — you can pass in your existing root reducer and any middleware you already have to createSlimReduxStore() .

More details on how to include slim-redux-react into your existing redux apps in this recipe and in the API reference for [createSlimReduxStore()](https://github.com/aGuyNamedJonas/slim-redux#createslimreduxstoreinitialstate-existingrootreducer-enhancer) .

Step #2: Create our counter component (just the presentational part)

Nothing fancy in this step — all we’re doing here is to create the counter component. Take a moment to look through the props that the counter component consumes:

  • props.counter which is the our counter state
  • props.increaseCounter which is a callback to increase the counter
  • props.decreaseCounter which is a callback to decrease the counter

Step #3: Create the change trigger definitions

This is where you encounter the first fundamental concept behind slim-redux-react: Actions and reducer definitions are bundled together into change triggers.

Change triggers bundle your action + reducer definitions. Everything you need to know about a specific store interaction in one place.


The beauty of change triggers is that you have everything you need to know about a specific store interaction in one place: Action type, the reducer code and optional action payload validation at a glance.

Also can you imagine how fast you can add new actions + reducers like that? No more navigating through a thousand files — just add an object to your change trigger definitions and import it wherever you need it.

Step #4: Create the container component for the counter


In this step we connect our slim-redux store to our Counter component.Notice how small the interface is!

Subcriptions: Map part of the state tree 🢂 props


Subscriptions are a simple mapping between part of the state tree and a prop. In this case we map the entire state to the props.counter.In a more complex state tree you can map a path in the state tree to the prop you want to pass to your component — for example:

subscriptions: { completeTodos: 'state.todos.completed'}

Subscriptions are implemented using the reselect library for optimal performance.

Change triggers are also very straight-forward but let me explain quickly what happens in the background:

When calling createSlimReduxStore() slim-redux creates a standard redux store, but injects the slim-redux functionality into it. On initializing the store slim-redux also injects the store.createChangeTrigger() function into the store (more on that in the API reference).

When working only in slim-redux, here’s how you would register and use a change trigger:

When passing in change trigger definitions to slim-redux-react’s slimReduxReact() function, store.createChangeTrigger() will be called in the background and the resulting change trigger functions are passed along to your component.

So in our case, the Counter component gets props.increaseCounter() and props.decreaseCounter() as the functions it can call to modify the (counter) state.

Additional resources

I realize this post might have been quite the flood of new information so far, so let me close off this introduction by providing you with the resources to learn more about slim-redux & slim-redux-react:

🢂 slim-redux repository on github (npm package)

Recipes:

🢂 slim-redux-react repository on github (npm package)

Recipes:

Closing words

The last two weeks of my life were exclusively dedicated to this project, so I really hope this is helpful to you. If you like these two projects, please be my new favorite human and give them a star on Github! :)

Also Dan Abramov, if you’re reading this: I didn’t steal your name “slim-redux”, I promise — I just saw now, after having finished this blog post, that you posted a pretty extensive gist by that name the other day. Sry about that! :)

Also I’d love to hear your thoughts, answer your questions and hear about suggestions for future development. So please don’t hesitate to get in touch on twitter.

And lastely a shameless plug: I’m currently looking for a full-time position as a react developer preferrably in Berlin. Know someone who might be interesting in hiring me? Please get in touch: [email protected]

Thanks! :)

Hacker Noon is how hackers start their afternoons. We’re a part of the @AMIfamily. We are now accepting submissions and happy to discuss advertising & sponsorship opportunities.

To learn more, read our about page, like/message us on Facebook, or simply, tweet/DM @HackerNoon.

If you enjoyed this story, we recommend reading our latest tech stories and trending tech stories. Until next time, don’t take the realities of the world for granted!