http://cn.redux.js.org/
这个是中文,本文只是看了之后总结一下发一下牢骚,总有内容基本上都是引用了这个链接的内容,请尊重原文翻译作者的权利。
但是做一下笔记看一下这个东西
redux我是从react了解到的,只是感觉js这块的框架很杂杂乱,诸子百家的东西太多,很多还不成熟,乱七八糟什么都有。什么都没有稳定下来,有想法的人轮子可以造N个。
且在介绍redux中也介绍了flux之类的。
redux也是从Flux和elm借鉴过来的
有些时候你想问他们,为什么你这么空,总是弄一些稀奇古怪的架构。
不过还好,没有人重新搞另外一个js,只是在js基础上在做一些封装。
创建一些新的游戏规则让你不愉快的玩耍。
首先安装
npm install --save redux
Redux是用ES2015做的,所以你不需要考虑Babel来预编译Redux(这点你会觉得做js这块工具链很长,军阀很多。
在这个介绍说的是redux和react结合的部分,所以还需要安装rect-redux的包
和redux的devtools工具。
感觉开发他们也做分层,有做core的代码的人,然后有做周边的工具,方便工程化的自动化的人。
npm install --save react-redux
npm install --save-dev redux-devtools
然后说了一个要点。
应用中所有的state都是一个对象树保存在一个单一的store中,唯一改变state的方法是触发action。一个描述发生了什么的对象,然后为了描述action如何改变state树,需要编写一个reducers(渲染)。
这个概念和react有点类似,或者一样。
react就是要求是不变的量,然后通过虚拟DOM来维护一个tree,当这个tree的某个点改变的时候,在全部推送给浏览器的内部DOM去刷新,这个可以提高效率。
你知道GUI的界面和Browser的区别么?GUI窗口是有坐标的概念,但是Browser的界面分辨率是动态的,包括很多为了适应不同的分辨率端,所以Browser的界面是一个stream的概念,但是GUI是一个网格的概念。这点还是不同的额,windows 的app也是消息机制,如果你看过比较早的MFC文档,你就知道其实很多事件都是挂在这个form的消息处理内,然后timer会触发解决。
这个非常类似于我们做Browser中各种element的listern处理,且为了提高效率,我们希望在Browser中是在最高层来接受和处理消息,由于这种冒泡的方式上传过来包含了消息接受者的ID,所以可以统一处理,这个和Browser有点类似。
但是windows的系统架构导致这个开销是比较小的,Browser开销比较大,大家都在想办法优化。
import { createStore } from 'redux';
/**
* 这是一个 reducer,形式为 (state, action) => state 的纯函数。
* 这里是一个箭头函数在react中喜欢用箭头函数来做
* 描述了 action 如何把 state 转变成下一个 state。
* 通过action来改变state
*
* state 的形式取决于你,可以是基本类型、数组、对象、
* 甚至是 Immutable.js 生成的数据结构。惟一的要点是
* 当 state 变化时需要返回全新的对象,而不是修改传入的参数。
*
* 下面例子使用 `switch` 语句和字符串来做判断,但你可以写帮助类(helper)
* 根据不同的约定(如方法映射)来判断,只要适用你的项目即可。
*/
function counter(state = 0, action) {
//一个计数的函数 counter
switch (action.type) {
//看action不同类别
case 'INCREMENT':
//提高
return state + 1;
case 'DECREMENT':
//减少
return state - 1;
default:
return state;
}
}
// 创建 Redux store 来存放应用的状态。
// API 是 { subscribe, dispatch, getState }。
// 一个store的容器
// 创建一个counter的容器
let store = createStore(counter);
// 可以手动订阅更新,也可以事件绑定到视图层。
// store的预定消息,就是记录到console去查看store的状态
store.subscribe(() =>
console.log(store.getState())
);
// 改变内部 state 惟一方法是 dispatch 一个 action。
// action 可以被序列化,用日记记录和储存下来,后期还可以以回放的方式执行
// 然后挂store的dispath,内容是incrament,表示 给store传一个事件
// INCREMENT 等等
// 代码会背了么?
store.dispatch({ type: 'INCREMENT' });
// 1
store.dispatch({ type: 'INCREMENT' });
// 2
store.dispatch({ type: 'DECREMENT' });
// 1
在原文中,提到了flux,说这个区别,我没有看过flux,所以这里不说了
后面有一个介绍视频的github的文章
https://egghead.io/series/getting-started-with-redux
https://egghead.io/series/getting-started-with-redux
介绍
动机
首先你要明白用JS后端开发的多半是单页应用开发,注意是单页,这里不是多页的原因是,多页涉及到刷新,既然我们有了异步的AJAX那么很多操作都可以在一个页面动态来做,这样用户体验感很好。
既然是单页,那么JS需要管理很多的state,JS需要知道用户输入完了没有,请求的数据返回了没有,原来在GUI下都很简单的事情,在Browser比较复杂,因为他娘就不是这样长的。
另外由于现在的JS非常喜欢异步,异步是一个好东西,但是变成比较复杂,我们开始学编程的时候都是同步,没有说到异步的东西。nginx为什么比apache,IIS牛,一个原因是他是异步的。
我们的web server也考虑异步了,那么在编程语言架构也需要考虑异步,我们的程序员也NB了,可以掌握异步的变成方式。
Redux 的核心概念
当普通对象使用state时,那么todo应用可能涨这个样子(你不觉得这句话没头没脑么?)
{
todos: [{
//吃饭,完成了
text: 'Eat food',
//
completed: true
}, {
// 做作业,还没按成
text: 'Exercise',
completed: false
}],
//查看过滤去,显示完成的
visibilityFilter: 'SHOW_COMPLETED'
}
这个对象就是Model,但是没有setter的修改方法,那么这个代码外部访问会有问题。
如果要改变state的数据,需要发起一个action,action就是一个普通的js对象
然后看一下下面的代码
// 定义了一个visiableFilter的函数,state是 SHOW_ALL
// 其实这个state是一个初始状态,当我在这里的时候,然后在输入一个变量,
// 我的状态改为下一个状态
// 然后看action传过来的信息有哪些
function visibilityFilter(state = 'SHOW_ALL', action) {
// 如果是看所有的,那么返回这个过滤器
if (action.type === 'SET_VISIBILITY_FILTER') {
return action.filter;
} else {
// 什么都不做,返回state
return state;
}
}
// todos的action
//
function todos(state = [], action) {
// 你发现没有对于action一般都用switch来做
switch (action.type) {
case 'ADD_TODO':
//改变了数据,然后返回一个数据内容这个数据内容应该传给remend去刷新
// 注意你的业务规则
return state.concat([{ text: action.text, completed: false }]);
case 'TOGGLE_TODO':
return state.map((todo, index) =>
action.index === index ?
{ text: todo.text, completed: !todo.completed } :
todo
)
default:
return state;
}
}
function todoApp(state = {}, action) {
// 然后定义一个todoApp大类,当action来的时候,返回
return {
todos: todos(state.todos, action),
visibilityFilter: visibilityFilter(state.visibilityFilter, action)
};
}
三大原则
单一数据来源
单个应用的state被保存在一个object tree中,每个object tree只能保存一个唯一的store
// counter 是一个单一的应用,他被保存在一个store中
//输出store的状态
console.log(store.getState())
/* 输出
{
visibilityFilter: 'SHOW_ALL',
todos: [
{
text: 'Consider using Redux',
completed: true,
},
{
text: 'Keep all state in a single tree',
completed: false
}
]
}
*/
State 是只读的
唯一的修改state的办法是用action
用纯函数来修改
这个概念是就是函数式编程,函数式编程没有很多乱七八糟的副作用
这个工作是reducer来做的
function visibilityFilter(state = 'SHOW_ALL', action) {
switch (action.type) {
case 'SET_VISIBILITY_FILTER':
return action.filter
default:
return state
}
}
function todos(state = [], action) {
switch (action.type) {
case 'ADD_TODO':
return [
...state,
{
text: action.text,
completed: false
}
]
case 'COMPLETE_TODO':
return state.map((todo, index) => {
if (index === action.index) {
return Object.assign({}, todo, {
completed: true
})
}
return todo
})
default:
return state
}
}
import { combineReducers, createStore } from 'redux'
let reducer = combineReducers({ visibilityFilter, todos })
let store = createStore(reducer)
先前技术
Redux 是一个混合物,
Flux
ELm
Immutable
Baobab
Rx
这里不介绍了,因为我没有过去
生态系统
Redux是一个小巧的库
文章推荐看一下 https://github.com/xgrommx/awesome-redux
还有很多内容,作为延伸可以进一步去看一下
示例
建议看一下,因为都比较简单,然后自己动手做一下