How to make Redux more concise
If you also think that Redux’s Boilerplate code and immutable data update make your code verbose, then this article may be the answer you’re looking for.
First, I’ll get a quick introduction to usm-redux
. It is an open source library based on Redux and Immer, and it makes your Redux code incredibly concise.
You don’t use writing cumbersome Redux boilerplate code, nor do you use to write cumbersome immutable data update operations code.
For example:
class Foo extends Module {
@state todos = { bar: { list: [] } }; @action
done(index, state) {
state.todos.bar.list[index].done = true;
}
}
- No type action
- No reducers
- No other boilerplate code
- Immutable data update more conveniently
More document details are here.
If you think
usm-redux
can solve your Redux problems, and your current project wants to try to migrate tousm-redux
, then here's a complete migration tutorial.
Migration from Redux Boilerplate Code
Use https://github.com/reduxjs/redux/tree/master/examples/todos as an example.
1. Create a migration module
create src/modules/Service/index.js
file:
import Module from 'usm-redux'
import todos from '../../reducers/todos'
import visibilityFilter from '../../reducers/visibilityFilter'export default class Service extends Module {
get _reducers() {
const reducers = this._getReducers(this.actionTypes, {})
return this._proto.combineReducers({
...reducers,
visibilityFilter,
todos,
})
}
}
2. Replace the store
Replace code in src/index.js
file:
const store = createStore(rootReducer)
To
const store = Services.create().store
🎉🎉🎉It’s work🎉🎉🎉
3. Dev new feature with usm module model
For example, we need develop counter feature.
4. Create 'src/modules/Counter/index.js'
file
import Module, { state, action } from 'usm-redux'export default class Counter extends Module {
@state count = 0 @action
add(state) {
state.count++
}
}
5. Add new module in 'src/index.js'
import Counter from './modules/Counter'
import Service from './modules/Service'const service = Service.create({ modules: { counter: new Counter() }})
const store = service.storerender(
<Provider store={store}>
<App service={service} />
</Provider>,
document.getElementById('root')
)
6. Add new featrue counter container in 'src/components/App.js'
import React from 'react'
import Footer from './Footer'
import AddTodo from '../containers/AddTodo'
import VisibleTodoList from '../containers/VisibleTodoList'
import Counter from '../containers/Counter'const App = ({ service }) => (
<div>
<AddTodo />
<VisibleTodoList />
<Footer />
<Counter service={service} />
</div>
)export default App
7. Add counter container 'src/containers/Counter.js'
import React from 'react'
import { connect } from 'react-redux'const Counter = ({ add, count }) =>
<button onClick={add}>
{count}
</button>
const mapStateToProps = (_, props) => ({
count: props.service.modules.counter.count
})const mapDispatchToProps = (_, props) => ({
add: () => props.service.modules.counter.add()
})export default connect(
mapStateToProps,
mapDispatchToProps
)(Counter)
🎉🎉🎉It’s done🎉🎉🎉
Note: You can also gradually migrate old redcers while developing it in the new module way.
8. Redux Middleware
For example, We use redux-logger
middleware, just create a base module.
import { applyMiddleware, createStore } from 'redux'
import logger from 'redux-logger'
import Module from 'usm-redux'class BaseModule extends Module {
static _generateStore(_, { reducers }) {
return createStore(
reducers,
applyMiddleware(logger)
)
}
}
usm-redux
will make you more enjoyable to use Redux.😄
This demo repo: https://github.com/unadlib/usm-redux-migration-demo
USM repo: https://github.com/unadlib/usm
Finally, if you want to learn more about the USM article: