共计 2907 个字符,预计需要花费 8 分钟才能阅读完成。
想一下,如果你需要写一个基于 Redux 的项目,你需要重复的写非常多的 Action Constants,非常多的 Action Creator 以做相当大一部分差不多相同的事情。
于是出现了为了帮你减少书写重复 Constants 及 Action Creator 的库 redux-act。
但只有 Redux 并不能完全满足我们的业务需求,毕竟 SPA 项目中总是需要从服务端获取数据的,于是这时候我们整合进来 Redux-saga。
Redux-saga 能非常好的帮助我们处理异步事件,但是同样的,Redux-saga 需要书写许多的 Action Creator 并指定其 Take 类型再合并到 Redux-Saga 的入口处,而且这些 Action Creator 及 effect 非但需要一一让参数对应,还不方便做统一的事件处理。
于是 Saga-action-creator 诞生了。
Saga-action-creator 的特性
- 减少重复繁琐的书写 Action creator
- 直观的参数传递
- 支持插件
- 保留了 Redux-saga 的所有特性
- 优秀的 Typescript 支持
- 更方便的测试
如何使用
使用 Saga-action-creator 的方法非常简单,只需 3 步
一、定义 Saga effects 并导出
import createSagaActions from 'saga-action-creator';
import {takeLatest, call} from 'redux-saga/effects';
import {getUserInfo, updateUser} from '../services/user';
const user = createSagaActions({
// 一般情况下,你可以直接写一个 Effect
*getUserById(id: string): Generator<any, any, any> {yield call(getUserInfo, id);
},
// 当然,如果你需要为某一个 Effect 指定 take 的类型
// 你可以传递一个对象,并指定 takeType 属性
updateUser: {
takeType: takeLatest,
*effect(id: string, name: string): Generator<any, any, any> {yield call(updateUser, id, { name});
},
},
});
export default user;
二、创建连接器并合并 Creators
import {createConnection, getLoadingPlugin} from 'saga-action-creator';
import user from './user';
import {takeLatest} from 'redux-saga/effects';
const creator = createConnection({
// 合并 creator
creators: {user,},
// 默认情况下 effect 的 take 类型为 `takeEvery`
// 如果你需要修改默认的类型可以传递这个参数
defaultTakeType: takeLatest,
// 添加插件
plugins: {
// 这里插件的 key 将作为后面 getReducers 的导出的 key,则为 store 名
loading: getLoadingPlugin(),},
});
export default creator;
三、将插件与 Redux 及 Redux-saga 进行连接
import {createStore, combineReducers, applyMiddleware} from 'redux';
import {all} from 'redux-saga/effects';
import createSagaMiddleware from 'redux-saga';
import creator from '../sagas';
// 将插件导出的 reducers 与 store 连接
const reducers = combineReducers({...creator.getReducers(),
});
const sagaMiddleware = createSagaMiddleware();
// 将 Effects 与 Redux-saga 连接
sagaMiddleware.run(function*() {yield all(creator.getEffects());
});
const store = createStore(reducers, applyMiddleware(sagaMiddleware));
export type AppState = ReturnType<typeof reducers>;
export default store;
至此,saga-action-creator 的连接动作就全部做完了。
剩下的,你就只需要像平时使用 action 一样使用 creator 为你导出的 Action Creator 了。
import {connect} from 'react-redux';
import {AppState} from '../store';
import userActions from '../sagaActions/user';
import UserList from './UserList';
const mapStateToProps = (state: AppState) => ({loading: state.loading.user.getUserById,});
const mapDispatchToProps = {getUserById: userActions.actions.getUserById,};
export default connect(
mapStateToProps,
mapDispatchToProps,
)(UserList);
总结
整个库非常的精简,旨在为你解决核心痛点。简化 Redux-saga 的书写,并保留其所有优点。
与历史项目整合也非常简单,不需要做过多的修改,使你可以渐进地优化你的项目。
该库使用严谨的 Ts 类型开发,并进行自动类型推倒,使你可以完全体会到 Ts 带来的开发乐趣。
该库支持插件,可以在所有的 Effect 前后执行所需的操作(这里开发的 loading 插件灵感源自 rematch,十分感谢)。
关于该库
该库开源并遵循 MIT 开源协议
源码地址:https://github.com/Justinidle…
写在最后
我们在招人????
我们是谁?
AfterShip 2012 年成立于香港,公司自 2014 年起已实现持续盈利,且每年 100% 增长,公司目前暂时不需要融资。业务遍布全球,与全球 500 多家物流公司达成合作,涉及 30 多种主流语言业务体系。客户有 Amazon, Wish, eBay, Paypal, Groupon, Etsy, 及各大小电商超过 100,000 家。
我们位于深圳南山互联网最繁华的地带。
关于岗位
我们前端全面使用 React.js 作为核心框架。如果你有一年以上的前端开发工作,熟悉 React.js,热爱各种最新技术,对代码有要求,欢迎给我你的简历:qc.zhu@aftership.com