1. umi
乌米,是可扩展的企业级前端应用框架。Umi 以路由为基础的,同时支持配置式路由和约定式路由,保证路由的功能完备,并以此进行功能扩展。然后配以生命周期完善的插件体系,覆盖从源码到构建产物的每个生命周期,支持各种功能扩展和业务需求.
2, redux解决方案--dva
• 通过把状态上提到 dva model 中,我们把数据逻辑从页面中抽离出来。
• 通过 effect 优雅地处理数据生成过程中的副作用,副作用中最常见的就是异步逻辑。
• dva model 中的数据可以注入给任意组件。
• 另外,dva 允许把数据逻辑再拆分(「页面」常常就是分隔的标志),以 namespace 区分。当你觉得有必要时,不同的 namespace 之间的 state 是可以互相访问的
如果你熟悉 React 中最基本的两个概念 props 和 state,一定知道 props 和 state 对于一个组件来讲都是数据的来源,而 state 又可以通过 props 传递给子组件,这像是一个鸡生蛋蛋生鸡的问题:到底谁是数据的源头 ?答案是 state,而且是广义的 state:它可以是 react 组件树中各级组件的 state,也可以是 react 组件树外部由其他 js 数据结构表示的 state,而 dva 管理的就是 react 组件树之外的 state: Redux。归根结底,props 是用来传导数据的,而 state 是数据改变的源泉。
3, Generator
调用 Generator
函数,返回一个遍历器对象,代表 Generator 函数的内部指针。以后,每次调用遍历器对象的next方法,就会返回一个有着value和done两个属性的对象。value属性表示当前的内部状态的值,是yield表达式后面那个表达式的值;done属性是一个布尔值,表示是否遍历结束。从另一个角度看,也可以说 Generator 生成了一系列的值,因为可以有任意多个yield, 这也就是它的名称的来历(英语中,generator 这个词是“生成器”的意思)。
function* helloWorldGenerator() {
yield 'hello';
yield 'world';
return 'ending';
}
var hw = helloWorldGenerator();
hw.next()
// { value: 'hello', done: false }
hw.next()
// { value: 'world', done: false }
hw.next()
// { value: 'ending', done: true }
hw.next()
// { value: undefined, done: true }
4, redux-saga
redux-saga 是一个用于管理应用程序 Side Effect(副作用,例如异步获取数据,访问浏览器缓存等)的 library,它的目标是让副作用管理更容易,执行更高效,测试更简单,在处理故障时更容易。
跟redux-thunk都是解决redux异步的解决方案,但是redux-saga比较强大,可以处理比较复杂的业务场景(多个异步相互调用).redux-thunk有点破坏redux原则,redux dispatch的是一个对象,redux-thunk有可能 dispatch的是个函数. redux-saga更加遵循redux原则,dispatch的是一个比较纯粹的action对象,其次基于generator,控制力更强,能处理比较复杂的业务场景
使用步骤
- 第一步; 创建saga.js文件
// store/index.js saga注册方式
import {createStore, applyMiddleware, combineReducers} from 'redux'
import logger from 'redux-logger' // 日志记录
import thunk from 'redux-thunk' // 异步处理方案
import {counterReducer} from './count.redux'
import creatSagaMiddleware from 'redux-saga' // 创建中间件
import mySaga from './saga'
// combineReducers 将多个reducer变成一个
// 1, 创建saga中间件并注册
const sagaMiddleware = creatSagaMiddleware()
const store = createStore(
combineReducers({'counter': counterReducer})
, applyMiddleware(logger, thunk, creatSagaMiddleware))
// const store = createStore(counterReducer, applyMiddleware(logger, thunk))
// 2, 中间件运行saga
sagaMiddleware.run(mySaga)
export default store
// store/saga.js
import {call, put, takeEvery} from 'redux-saga/effects'
// takeEvery 全局监听器
const userService = {
login(uname) {
return new Promise((resolve, reject) => {
setTimeout(() => {
if (uname === 'Jerry') {
resolve({id: 1, name: 'Jerry', age; 20})
} else {
reject('用户名或密码错误')
}
}, 1000)
})
}
}
function* login(action) {
try {
yield put({type: 'requestLogin'})
const result = yield call(userService.login, action.uname)
yield put({type: 'loginSuccess', result})
} catch (message) {
yield put({type: 'loginFailure', message})
}
}
function* mySaga() {
yield takeEvery('login', login)
}
export default mySaga
// store/user.redux.js reducer操作
const init = {
isLogin: false,
loading: false,
error: ''
}
export const user = (state = init, action) => {
switch (action.type) {
case 'requestLogin':
return {
isLogin: false,
loading: true,
error: ''
};
case 'loginSuccess':
return {
isLogin: true,
loading: false,
error: ''
};
case 'loginFailure':
return {
isLogin: true,
loading: false,
error: action.message
};
default:
return state
}
}
// action creator
export function login(uname) {
return {type: 'login', uname}
}