redux介绍 1

来源:互联网 发布:云计算p层 编辑:程序博客网 时间:2024/05/29 11:07

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-reduxnpm 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' });// 1store.dispatch({ type: 'INCREMENT' });// 2store.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

还有很多内容,作为延伸可以进一步去看一下

示例

建议看一下,因为都比较简单,然后自己动手做一下