Image courtesy of OpenWorld

Redux without reducers: Reduxless

Djamel Hassaine
DailyJS
Published in
3 min readMay 11, 2018

--

A small and performant state management and routing library with unidirectional data flow.

Before I introduce Reduxless, I just want to say that Redux is actually a great way to manage state in your applications, and if you do choose to use it in your project, then you’ve made a good decision, especially if you incorporate design patterns like Ducks and Ducks++.

As great as Redux is though, it does unfortunately involve a fair amount of boilerplate code and there can be a bit of a learning curve to overcome because of the number of moving parts to consider, for example: reducers, actions, action types, selectors, and middleware. However, a lot of this complexity can be eliminated by removing the dispatch and reduce stage, which is what Reduxless does. I should point out though that the idea isn’t novel. Since implementing Reduxless, I discovered Redux zero has the same concept. But you might still want to consider using Reduxless, because it is performant (see this); has bindings for React and Preact; allows middleware; ships with a simple routing mechanism; provides a very efficient selector memoizer; and supports state validation. And it’s only 2.5KB!

The general gist

The following snippet of code demonstrates how Reduxless can be used with a React-like library (in this case, Preact):

import { h, render } from 'preact';
import { createStore, Container, mapper } from 'reduxless/preact';

const store = createStore({ name: 'Bart Simpson' });

const Component = ({name, updateName}) => (
<p onClick={
() => updateName(name == 'Bart Simpson' ? 'Lisa Simpson' : 'Bart Simpson')
}>
Hello there, {name}! Click to change me.
</p>
);

const MappedComponent = mapper(
{
// selectors
name: store => store.get('name')
},
{
// actions
updateName: (store, ownProps, newName) => store.set('name', newName)
}
)(Component);

render(
<Container store={store}>
<MappedComponent />
</Container>
)

If you are using Preact, then you pull your imports from reduxless/preact, whereas if you’re using React, it would be reduxless/react.

You create the store and optionally pass in the initial state with createStore({ name: ‘Bart Simpson’ })

The Container is basically the same as Redux’s Provider, which allows nested children components to have access to the store via Context.

Notice that the click handler on the p element simply updates the store directly by replacing a sub-tree of the state. As with Redux, it’s critical that the state is replaced and not simply mutated. If you don’t do this, then your components may not be re-rendered.

Instead of using a function called connect to map the actions and selectors to props, there is a function called mapper. The name mapper was deliberately chosen because it behaves differently:

  • The first argument is an object where the keys correspond to the prop names that get passed to the mapped Component and the values are the selector functions that Reduxless invokes with the store.
  • The second argument is an object containing all the actions. When the actions are invoked, Reduxless injects the store, and the props that the mapped Component receives before any other arguments.

Summary

I’ve shown a minimal example of using Reduxless, but it is capable of much more, especially when you use all the built-in features.

Please take a look at the GitHub page for more information, and give it star if you like it.

--

--