DvaJS
阅读数:90 评论数:0
跳转到新版页面分类
html/css/js
正文
dva是一个基于redux和redux-sage的数据流方案, 然后为了简化开发体验, dva还额外内置了react-router和fetch.
redux
Redux是Javascript状态容器, 提供可预测化的状态管理.
那什么是可预测化, 我的理解就是根据一个固定的输入, 必然会得到一个固定的结果.
1. 三大原则
(1) 单一数据源
使用redux的程序, 所有的state都存储在一个单一的数据源store内部, 类似一个巨大的对象树.
(2) state是只读的
能改变state的唯一方式是通过触发action来修改.
(3)使用纯函数执行修改
为了描述action如何改变state tree, 你需要编写reducers.
reducers是一些纯函数, 接口当前state和action. 只需要根据action, 返回对应的state. 而且必须要有返回.
一个函数的返回结果只依赖于它的参数, 并且在执行过程里面没有副作用, 我们就把这个函数叫做纯函数.
2. action
action就是动作, 也就是通过动作来修改state的值, 也是修改store的唯一途径.
action本质上就是一个普通js对象, 我们约定这个对象必须有一个字段type, 来表示我们的动作名称.
此外, 我们还会希望state变成什么样子的对应值通过action传进来, 那么这里action可能会类似这样子的
{
type: 'TOGGLE_TODO',
index: 5
}
3. reducer
reducer作为纯函数, 内部不建议用任何有副作用的操作, 比如操作外部的变量, 任何导致相同输入但输出却不一致的操作.
4. connect方法
把组件和store连接起来, connect接受4个参数, 分别是mapStateToProps, mapDispatchToProps, mergeProps, options
connect([mapStateToProps], [mapDispatchToProps], [mergeProps], [options])
mapStateToProps(state, ownProps)方法允许我们将store中的数据作为props绑定到组件中,只要store更新了就会调用mapStateToProps方法, mapStateToProps返回的结果必须是object对象, 该对象中的值将会更新到组件中.
const mapStateToProps = (state) => {
return ({
count: state.counter.count
})
}
mapDispatchToProps(dispatch,[ownProps])允许我们将action作为props绑定到组件中, mapDispatchToProps希望你返回包含对应action的object对象.
redux-sage
redux-sage是一个用于管理应用程序Side Effect( 例如异步获取数据)的library,, 它使用的ES6的Generator功能, 让异步的流程看起来就像是标准同步的Javascript代码.
generator是ES6提供的一种异步编程解决方案,最简的generator函数, 其实它就是一个普通的函数, 但是它有两个特征:
(1) function关键字与函数名之间有一个*号.
(2) 就是函数体内使用yield表达式来遍历状态
function* newGenerator(){
yield 'hello';
yield 'world';
return 'ending';
}
执行generator函数之后, 该函数并不会立即执行, 返回的也不是函数运行结果, 而是一个指向内部状态的指针对象. 通常使用遍历器对象的next方法.使得指针移向下一个状态. 每一次调用next()方法, 内部指针就从函数头部或上一次停下的地方开始执行, 直到遇到下一个yield表达式位置, 由此可以看出, generator是分段执行的, yield表达式是暂停执行的标记, 而next方法可以恢复执行.
es6 fetch
1. promise
Promies是一个异步操作, 分为三种状态: Pending(进行中), Resolved(已完成)和Rejected(已失败).
var promise = new Promise((resolve,reject)=>{
// ...
if (/* 异步操作成功 */){
resolve(res);
} else {
reject(error);
}
})
//Promise 实例生成以后,可以用then方法分别指定Resolved状态和Reject状态的回调函数。
var promise = new Promise((resolve,reject)=>{
// ...
}).then(res=>{
//成功
resolve(res);
}, err=>{
//失败
reject(err);
})
2. fetch
fetch是基于Promise设计的,
fetch(url).then(function(response) {
return response.json();
}).then(function(data) {
console.log(data);
}).catch(function(e) {
console.log("Oops, error");
});
fetch(url).then(response => response.json())
.then(data => console.log(data))
.catch(e => console.log("Oops, error", e))
Dva
1. 数据流向
数据的改变通常是通过用户交互行为或者浏览器行触发的, 当此类行为会改变数据的时候可以通过dispatch发起一个action, 如果是同步行为,会直接通过reducers改变state, 如果是异步行为, 会先触发Effects, 然后流向Reducers最后改变State,.
2. Models
(1) state
表示Model的状态数据.
(2)action
action必须带有type属性指明具体的行为, 如果要发起一个action需要使用dispatch函数, dispatch是在组件connect Models以后, 通过props传入的.
dispatch({
type: 'user/add', // 如果在 model 外调用,需要添加 namespace
payload: {}, // 需要传递的信息
});
(3)reducer
type Reducer<S, A> = (state: S, action: A) => S
reducer函数接受两个参数: 之前已经累积运算的结果和当前要被累积的值, 返回的是一个新的累积的结果.
(4) effect
effect被称为副作用, 最常见的就是异步操作.
(5) subscription
根据条件dispatch需要的action
import key from 'keymaster';
...
app.model({
namespace: 'count',
subscriptions: {
keyEvent({dispatch}) {
key('⌘+up, ctrl+up', () => { dispatch({type:'add'}) });
},
}
});
(6)Router
这里的路由指的是前端路由, 通过浏览器提供的history api可以监听浏览url的变化, 从而控制路由相关操作.