A concise design that completely changed Redux
It’s been almost four years since the first Redux commit. During this time, there are a variety of encapsulation practices for Redux, in which OOP design is particularly prominent, and usm-redux
is a completely changed Redux inherent usage of the library.
Basically, usm-redux
is a Redux re-encapsulation library that is completely created for OOP, making the use of Redux incredibly concise.
Let’s first look at a classic Todo example in Redux official document:
import { createStore, combineReducers } from 'redux'// action
let nextTodoId = 0
const addTodo = text => {
return {
type: 'ADD_TODO',
id: nextTodoId++,
text
}
}const setVisibilityFilter = filter => {
return {
type: 'SET_VISIBILITY_FILTER',
filter
}
}const toggleTodo = id => {
return {
type: 'TOGGLE_TODO',
id
}
}// reducers
const todos = (state = [], action) => {
switch (action.type) {
case 'ADD_TODO':
return [
...state,
{
id: action.id,
text: action.text,
completed: false
}
]
case 'TOGGLE_TODO':
return state.map(todo =>
(todo.id === action.id)
? {...todo, completed: !todo.completed}
: todo
)
default:
return state
}
}const visibilityFilter = (state = 'SHOW_ALL', action) => {
switch (action.type) {
case 'SET_VISIBILITY_FILTER':
return action.filter
default:
return state
}
}const todoApp = combineReducers({
todos,
visibilityFilter
})
It’s just about writing a simple todo, but that’s obviously Redux’s boilerplate.
Here is a usm-redux
Todo example (exactly the same logical implementation as above):
import Module, { state, action } from 'usm-redux'class TodoList extends Module {
@state todos = []
@state visibilityFilter = 'SHOW_ALL'
nextTodoId = 0 @action
add(text, state) {
this.nextTodoId++
state.todos.push({
text,
id: this.nextTodoId,
completed: false,
})
} @action
toggle(id, state) {
const todo = state.todos.find(todo => todo.id === id)
todo.completed = !todo.completed
} @action
setVisibility(filter, state) {
state.visibilityFilter = filter
}
}
usm-redux
has only the definitions of @state
and @action
, in addition, it's exactly the same as the OOP of the class
that you often use.
In a comparison between a fully equivalent TODO examples, we can see that the usm-redux
logic code is close to the way it is closer to OOP, making it easy for people who want to use OOP. At the same time usm-redux
also provides a decorator @computed
cache for computing derived data.
class Shop extends Module {
@state goods = [];
@state status = 'close'; @action
operate(item, status, state) {
state.goods.push(item);
state.status = status;
}
// call -> this.operate({ name: 'fruits', amount: 10 }, 'open'); @computed
shortages = [
() => this.goods,
(goods) => goods.filter(item => item.amount < 5)
];
}
The modular usage of usm-redux
will make your project also has more cohesion with business logic. At the same time with React Hooks, let React+Redux easily reach high cohesion and low coupling.
BTW, usm-redux
is a concept based on the universal state module designed usm
. Simply, usm
is a way to make it easy for you to use mainstream state libraries such as Redux, Vuex And MobX without bothering to learn and use them separately.
For more information about usm-redux
and usm
, here is this repo: https://github.com/unadlib/usm