Redux

REDUX

1.redux究竟是个什么玩意 ?

​ 如果要谈起redux,我们必须要了解什么叫做 函数式编程 ,其实我们程序的组件开发属于函数式编程的升级版,函数式编程带给我们的优势可以说非常之多,什么功能划分更容易,什么维护更简便,什么高内聚低耦合等等优势在此不再赘述,主要谈一谈函数式编程的缺点。

1. 函数式编程容易编程链式调用的模式。
function foo(){
    var  a = funA();
    var  b = funB();
    return funC(b);
}
function funA(arg){
    return arg + 1;    
}
function funB(arg){
    return arg + 2;
}
function funC(arg){
    return arg + 3;
}

​ 类似于这样的函数在开发之中带给我们的困扰可以说是相当之多了,那么问题来了,我们为什么要用这样的模式编写函数那?

​ 因为函数的作用域是独立的, 所以我们在函数之间进行数据通讯的时候往往需要通过传递参数或者使用bind等方法进行参数传递,这样的方式带给我们的就是函数之间的紧密耦合,如何进行解耦那,我们需要用到全局变量进行函数之间值的传递, 可是这样真的解决问题了么?

​ 这样的做法解决了一个问题,但是其他问题就会如雨后春笋一般冒出来,全局变量浪费内存,全局变量不安全,全局变量.... ,办法总比困难多,对于这样的数据共享我们其实可以使用订阅发布模式解决问题,但是订阅发布就万无一失了么?

2. 数据驱动模型的实现。
数据驱动.png

​ 对于这样的需求我们往往需要使用订阅发布模式进行实现,但是订阅发布的封装又出现了n种方案,怎么办?

​ 其实说到这里我们好像知道了一件事,问题的解决方案有了,但是我们实际上是欠缺一个统一的标准对我们的需求(函数与函数或者组件与组件之间的通讯)进行统一,这个标准不一定是最优的但是需要应用范围要广。

​ 这个时候flux架构出现了。

2. flux架构

flux架构就像是眼镜,你自然知道什么时候需要他

​ flux的横空出世好像是踏着五彩祥云的至尊宝,拯救万千前端于水火之中,但是这个至尊宝有点麻烦。

flux架构.png

​ 这是flux的架构图,你甚至不需要看懂,只需要知道整个架构的复杂程度还是非常高的,在flux之中想要更改数据仓库(store),我们需要调用dispather,在dispather之中手动调用 store之中的set方法,去更改状态,我们在开发企业级项目的时候,往往会维护一个非常庞大的store,这时候我们面对这样异常敏感而且不易排错的功能,可以说如履薄冰。

​ 然后钢铁侠替代至尊宝来接你了。

3.redux

​ 可以说redux就是flux架构的简化版,虽然还是很难,但是相对flux而言,redux把一些易错的操作进行了内部封装,这些封装使得报错风险急剧下降。

​ 比较现成的东西就一定是量身订造的东西,虽然redux可以完全独立使用,可以配合任何框架实现基础功能但是我们最多的使用redux的地方还是在react之中,为啥那?

​ 我们考虑的框架有两款,vue有比较现成的vuex, react那, fb的工程师更推荐使用redux,因为redux和react有更高的契合度有更丰富的合作生态如 react-redux等。

4. redux使用详解

**part 1 : 看懂一张图 **

image.png

​ 这张图基本说明了使用redux的全部内容,但是想要读懂这张图可能对于绝大多数小伙伴来说比较困难,怎么办呐? 不要放弃,我们先学一下基本操作,过一会再回头来看这张图。

  1. redux 是干嘛的 ?

    一句话解释 : 其实redux就是用来进行函数,组件之间数据共享的。

    1. redux怎样进行数据共享那 ?

    一句话解释 : 就是把一个对象放进数据仓库之中。

    1. redux是否实现了发布订阅模式那 ?

    一句话解释 : 实现了,这是后话。

所以我们大致了解了redux,那么我们用一个极简的翻译来看一下这个图。

中文redux示意图.png

这张图之中尤其要注意的是创建状态状态区分处理器, 这两个部分之间的绿色箭头,在通过数据仓库时这个线是虚的,也就是说,本质上来讲是状态区分处理器最终将状态放入了数据仓库之中,可是为什么这条线要先经过数据仓库那 ?

​ 敲黑板的重点来了 :

​ 创状态这个功能其实会创建一个对象,这个对象会被 dispatch方法直接派发到 数据仓库之中,但是数据仓库又需要去进行一个状态区分和处理,这个区分和处理是被直接集成在数据仓库之中的,相当于仓库分拣员 , 这个分拣员会自动将创建好的对象进行分类,分类后放入仓库。

数据仓库内部一旦发生改变了,那么视图就会发生相应的改变,这就是redux完整的流程。

但是这个完整的流程之中有非常之多的注意事项,如果你已经理解了以上的内容,那么就可以继续向下学习redux操作实例了。

为了方便操作,我们使用 create-react-app 脚手架工具搭建react环境,并使用 redux进行开发 , 编写redux实例,同时为了使用的安全和严谨,请务必参考 redux官方文档,其余野路子博客不建议查看。

redux官方文档

part 2 : 记得三个单词

​ 1. action 这货就是我们刚才说的数据对象,这个对象就是JavaScript的单纯的对象。 就是下面这样的

var action = {
    name : "一个对象"    
}
2. action 还有一些小小的矫情,就是必须有某些东西,这个东西就叫做 `type`, 我们在创建action的时候通常会创建这样的一个对象
let action = {
    type : MY_FIRST_ACTION,
    payload : {
        text : "随便写一些文本"
    }
}

我们写的这个对象大概就是action了,但是我们想要创建茫茫多个action怎么办呐 ? 记得我们有一个创建器就好了,这个创建器叫做 actionCreater

3. actionCreate长成这样 , 我们通常定义 action之中type的时候会使用`常量`。

action.js

/*
*   常量定义,这个常量仅代表状态。
*/
export const INCREASE_NUMBER = "INCREASE_NUMBER";
export const REDUCE_NUMBER = "REDUCE_NUMBER";
export const INIT_NUMBER = "INIT_NUMBER";

export function increaseNumber(number){
    return {
        type : INCREASE_NUMBER,
        payload : {
            number 
        }
    }
}

export function reduceNumber(number){
    return {
        type : REDUCE_NUMBER,
        payload : {
            number 
        }
    }
}
4. 我们要设计一下我们当前state 的数据结构,这个数据结构方便我们后续的操作。
{
    calculationNumber :{
        type : INIT_NUMBER,
        payload : {
            number : 0
        }
    }
}

这大概就是一个及其简单的数据结构了。

5. 开发状态区分处理器 reducer

​ reducer接受两个参数 reducer( prevState, state) , 即为原始状态和更新状态 , 请务必记住reducer的特性,reducer是一个纯函数,这意味着 同样的输入,同样的输出,如果输入同样的内容那么输出一定是一致的,这就是纯函数。 在这里不能调用 Date.now() ,或者 Math.random() 等方法。

reducer.js

import {
    INCREASE_NUMBER,
    REDUCE_NUMBER,
    INIT_NUMBER
} from "./action"

function calculation(state = initialState , action){
    switch(action.type){
        case INCREASE_NUMBER : 
            return Object.assign({},state,{
                ...action,
                payload : {
                    number : state.payload.number ++
                }
            });
        case REDUCE_NUMBER : 
            return Object.assign({},state,{
                ...action,
                payload : {
                    number : state.payload.number --
                }
        });
        default : return state;
    }
}

export calculation;

6. 最后我们引入我们的主角

store.getState()用来获取store完整数据。

store.subscribe() 用来监听完整数据。

import {createStore} from "redux";
import reducer from "./reducer";
let store = createStore(reducer);
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 211,042评论 6 490
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 89,996评论 2 384
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 156,674评论 0 345
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,340评论 1 283
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,404评论 5 384
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,749评论 1 289
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,902评论 3 405
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,662评论 0 266
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,110评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,451评论 2 325
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,577评论 1 340
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,258评论 4 328
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,848评论 3 312
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,726评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,952评论 1 264
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,271评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,452评论 2 348

推荐阅读更多精彩内容