React-redux是一件好事。 如果正确使用,则应用程序体系结构是有效的,并且项目结构易于阅读。 但正如任何决定一样,有一些特殊之处。
动作和减速器的描述就是这样的功能之一。 这两个实体在代码中的经典实现是一项非常耗时的任务。
经典实施的痛苦
一个简单的例子:
输出包含3个文件,至少包含以下问题:
- 只需添加新的动作链即可“膨胀”代码
- 过量导入动作常数
- 读取动作常量名称(单独)
最佳化
可以通过
redux-actions改进此示例。
import { createActions, handleActions, combineActions } from 'redux-actions' export const actions = createActions({ popups: { open: { start: () => ({ loading: true }), pending: () => ({ loading: true }), fail: (error) => ({ loading: false, error }), success: (name, data) => ({ loading: false, name, data }), }, close: { start: () => ({ loading: true }), pending: () => ({ loading: true }), fail: (error) => ({ loading: false, error }), success: (name) => ({ loading: false, name }), }, }, }).popups const initialState = { opened: [] }; export const accountsReducer = handleActions({ [ combineActions( actions.open.start, actions.open.pending, actions.open.success, actions.open.fail, actions.close.start, actions.close.pending, actions.close.success, actions.close.fail ) ]: (state, { payload: { loading } }) => ({ ...state, loading }), [combineActions(actions.open.fail, actions.close.fail)]: (state, { payload: { error } }) => ({ ...state, error }), [actions.open.success]: (state, { payload: { name, data } }) => ({ ...state, error: null, opened: [ ...(state.opened || []).filter(x => x.name !== name), { name, data } ] }), [actions.close.success]: (state, { payload: { name } }) => ({ ...state, error: null, opened: [ ...state.opened.filter(x => x.name !== name) ] }) }, initialState)
已经好多了,但完美无止境。
治疗疼痛
为了寻求更好的解决方案,我遇到了
LestaD habr.com/en/post/350850/#comment_10706454的评论,并决定尝试使用
redux-symbiote 。
这样可以删除不必要的实体并减少代码量。
上面的示例看起来像这样:
从专业人士那里,我们有:缺点:- IDE并不总是提供提示
- 很难在代码中寻找行动
- 难以重命名动作
尽管有缺点,但该模块已在我们的项目中成功使用。
感谢
LestaD的出色工作。