首先在看代码之前让我们一起回顾下redux的思想吧   首先redux就是一个MVC思想的框架,他总体是遵循数据的单向流动自顶向下流动

在我们仓库中有一个initState用来存储着我们的初始数据 另外还有个actions这个用来进行一些变量的改变和传递 也就是MVC结构中的C---控制层

另外里面的reducer是对应着MVC中M层 用来进行逻辑的处理  注意这里的逻辑处理不能操作UI逻辑也就是直接控制视图的变量

  当我们用户想要改变数据的时候必须触动actions让其去操作reducer然后进行数据的改变,而不能让用户直接去操作我们state中的数据

  获取数据的时候也是同理 不能让其对数据库直接操作

先介绍下redux的使用  代码如下

 //引入redux中创建仓库的方法

 import {createStore,combineReducers} from "redux";

 const initState={
num:0
} let reducer=(state=initState,action)=>{ switch (action.type) {
case "BIG":
state=action.data
return state; default:
return state;
}
} const reducers=combineReducers({reducer}) const store=createStore(reducers);
export default store;

这是仓库的一些写法,而我们使用的时候   引入store 直接 调用下面这个方法

store.dispatch({type:"LIST_ADD",list:[1,2,3]})  
获取值要放在订阅模式中  防止仓库改变但是页面不能同步更新 所以此时发布订阅模式就派上了用场
store.subscribe(()=>{
this.setState({
hello: store.getState()
})
})

  以上介绍的是redux中的使用,下面是模拟这个效果进行的封装
先展示一个简单版
 class Flux{
constructor(opj){
//将接受到的这个对象挂载到这个class实例上
Object.assign(this,opj)
this.arr=[]
}
getState(attr){
//这里接受到的这个attr是让用户想取哪个值
//这个方法是暴露给仓库的一个获取仓库数据的方法
if(attr){
return this.reducer(this.state,{})[attr]
}else{
return this.reducer(this.state,{})
}
}
dispatch(actionType){
//这里接受到的是一个对象
//console.log(this.state,"封装的方法")
//将最新的state获取出来保存起来 然后下次再调用getState方法的话就不会
//在读取默认值了
this.state=this.reducer(this.state,actionType) //当用户修改值得时候我们每次发布一下
this.promulgator("storeChange")
}
subscriber(cb){
//订阅者 将订阅函数储存在事件队列中
this.arr.push(cb)
}
promulgator(){
//发布者 触发订阅者中的函数
this.arr.forEach(cb=>{
cb()
})
}
} export default Flux;

看完上述的方法不知道大家有没有发现什么问题

  在外面其实可以通过实例访问到里面state和reducer   既然能够访问到那么就证明使用者可以不通过我们规定的方法去直接修改数值

这样就与我们封装的数据单向流动 每次用户想要改变数据必须通过actions找到对应的reducer去修改的初衷了,所以我们需要对其进行一些

改正 让调用这个方法的时候只能通过我们暴露给用户的方法去改变,而不应该有其他的接口存在

具体改正如下

let state=Symbol("state")

//因为我们不能将this上暴露出state 不然用户可以访问到 所以这里要用到Symbol

class Flux{
constructor(opj){
//将接受到的这个对象挂载到这个class实例上
//Object.assign(this,opj)
//不能用Object.assign的原因是因为state不能暴露在这个实例上
//防止用户的修改 this.reducer=opj.reducer;
this[state]=opj.state this.arr=[]
}
getState(attr){
//这里接受到的这个attr是让用户想取哪个值
//这个方法是暴露给仓库的一个获取仓库数据的方法
if(attr){ return this.reducer(this[state],{})[attr]
}else{
//加三个点的作用是让用户只读不能改
//还有一个方法 Object.getOwnPropertyDescriptor(this.state)
//里面某个属性设置成false就不能改了 return {...this.reducer(this[state],{})}
}
}
dispatch(actionType){
//这里接受到的是一个对象
//console.log(this.state,"封装的方法")
//将最新的state获取出来保存起来 然后下次再调用getState方法的话就不会
//在读取默认值了
this[state]=this.reducer(this[state],actionType) //当用户修改值得时候我们每次发布一下
this.promulgator()
//这个发布订阅的作用是为了防止数据改变用户得不到 也就是将视图和用户连接起来
}
subscriber(cb){
//订阅者 将订阅函数储存在事件队列中
this.arr.push(cb)
}
promulgator(){
//发布者 触发订阅者中的函数
this.arr.forEach(cb=>{
cb()
})
}
} export default Flux;

具体使用方法如下  基本同redux一样

 import Store from  "../tool/index"

 let initState={
num:1
} export let actions= {
addNum(text){
return {
type:"ADDNUM",
text
}
}
} let reducer=(state=initState,action)=>{
switch (action.type) {
case "ADDNUM":{
let num=state.num+1 return {...state,...{num}}
}
default: return {...state};
}
} //引入我们封装的flux框架 然后将reducer传入 并且将action传入 //注意这里接受的是对象
export default new Store({
reducer,
state:initState
})

redux之createStore方法底层封装模拟的更多相关文章

  1. redux中createStore方法的默认参数

    一般使用方法: createStore(reducer, applyMiddleware(thunk)) 传递默认参数: createStore(reducer, defaultState, appl ...

  2. Redux状态管理方法与实例

    状态管理是目前构建单页应用中不可或缺的一环,也是值得花时间学习的知识点.React官方推荐我们使用Redux来管理我们的React应用,同时也提供了Redux的文档来供我们学习,中文版地址为http: ...

  3. 【类库】私房干货.Net数据层方法的封装

    [类库]私房干货.Net数据层方法的封装 作者:白宁超 时间:2016年3月5日22:51:47 摘要:继上篇<Oracle手边常用70则脚本知识汇总>文章的发表,引起很多朋友关注.便促使 ...

  4. 【SSM 7】Mybatis底层封装思路

    一.基本概述 在前面的博客中介绍到Mybatis的逆向生成工具,为我们生成了每个实体的基本增删改查的代码,那么每个实体都是那么多的代码,我们很容易的发现,有很大的相似性.对于这部分代码,应该予以抽象封 ...

  5. ASP.NET底层封装HttpModule实例---FormsAuthentication类的分析

    HttpModule是用来注册HttpApplication事件的,实现IHttpModule接口的托管代码模块可以访问该请求管道的所有事件.那么对于我们最常用的ASP.NET Forms身份验证模块 ...

  6. Android+appium +python 点击坐标tap方法的封装

    当常使用的查找点击元素的方法name.id.classname等无法使用时,我们将会采取坐标的点击来实现操作,同样存在一个问题,当手机的分辨率.屏幕大小不一致时,坐标的定位也会不同,因此将采用相对坐标 ...

  7. react中界面跳转 A界面跳B界面,返回A界面,A界面状态保持不变 redux的state方法

    在上一篇文章中说过了react中界面A跳到B,返回A,A界面状态保持不变,上篇中使用的是传统的localStorage方法,现在来使用第二种redux的state方法来实现这个功能 现在我刚接触red ...

  8. Redux的createStore实现

    Redux的createStore实现   使用过react的同学应该对Redux这个东西有所了解.他是一种全局状态管理的思想(对, 这里我觉得它是一种思想, 因为对于React来说, 其实Redux ...

  9. ArrayList类中的contains()方法底层依赖的是equals()方法

    ArrayList类中的contains()方法底层依赖的是equals()方法.若集合中的元素是自定义对象,则应该重写该类父类Object的equals()方法,否则对象永远都不相同(因为都是new ...

随机推荐

  1. Spring Bean 作用域

    Bean 的作用域 当在 Spring 中定义一个 bean 时,你必须声明该 bean 的作用域的选项.例如,为了强制 Spring 在每次需要时都产生一个新的 bean 实例,你应该声明 bean ...

  2. Nginx1.10.2安装配置

    以下操作均在当前用户目录操作(root的目录,截止2016.11.2最新版本) 1.安装常用工具及基础包:yum -y install wget git vim make gcc gcc-c++ op ...

  3. Apache-Shiro分布式环境配置(与redis集成)(转)

    原文戳我 前段时间项目要用到权限控制的相关模块,经过讨论决定采用Apache下面的Shiro开源框架进行身份校验与权限控制,因项目需部署在集群环境下,所以需要分布式的支持,故配置了Redis作为权限数 ...

  4. 一段简单简介的JAVA内存分页代码

    1.原因 工作中有的时候我们要处理的分页是无法全部用数据库去处理的,因为有些业务数据需要计算,所以我们需要把数据拿到程序中去分页 2.代码 //前端传入分页参数 Pageable pageable = ...

  5. CentOS7 安装 Nginx 1.12.1

    安装准备: nginx 依赖的一些 lib 库: yum install gcc-c++ yum install pcre pcre-devel yum install zlib zlib-devel ...

  6. 洛谷P1969 [NOIP2013提高组Day2T1] 积木大赛

    P1969 积木大赛 题目描述 春春幼儿园举办了一年一度的“积木大赛”.今年比赛的内容是搭建一座宽度为n的大厦,大厦可以看成由n块宽度为1的积木组成,第i块积木的最终高度需要是hi. 在搭建开始之前, ...

  7. CenOS SSH无密码登录

    系统环境:CentOS6.8 软件环境:SSH(yum -y install openssh-clients) IP   地址:192.168.0.188 用户环境:root.xiaoming  系统 ...

  8. 让Drewtech的J2534 ToolBox 软件支持任何J2534的设备

    更改windows注册表中的FunctionLibrary和ConfigApplication,将DLL和exe路径替换原来的,其他不要动. 或者 create second key in regis ...

  9. 阿里云合作伙伴峰会SaaS加速器专场 | 商业加持,迈进亿元俱乐部

    导语:本文中,阿里云智能运营专家朱以军从宏观角度分析了SaaS市场的机遇和挑战,重点介绍了阿里云的商业操作系统.同时,阿里云SaaS加速器也在招募更多ISV合作伙伴和我们一起共创专注面向未来的应用,用 ...

  10. 几道面试题-考察JS的运用

    1.定义一个方法,传入一个string类型的参数,然后将string的每个字符间加个空格返回,比如: spacify('hello world') // => 'h e l l o  w o r ...