0x000 概述

这一章开始讲redux,其实是承接前面的react,但其实作为一个框架来说,reduxreact并没有太多的关系,本身是独立存在的。在我看来它们的关系不会比共用re开头更深了,所以我就重新开了一个头,但其实是基于前面写的...

0x001 redux资源

  • 中文文档
  • 英文文档
  • 官方视频

0x002 学习历程

当初为了学习redux,看了许多的材料,中途曾经放弃两次,但是最后还是勇敢的拿起了它,现在终于勉强弄懂。

  • 第一次是大家都说redux牛逼,所以就打算学习一下,看了许多遍了redux中文文档,也看了英文文档--因为有些demo总是跑的不成功,怕是中文更新不及时的原因。但最后还是不了了之,因为不知道用它来干啥,反倒弄出了一堆的reduceraction之类的东西。
  • 第二次是在做毕业设计的时候,做了一个类似看板一样的api自动测试及性能统计分析项目--类似postman,在这里遇到了一些超级棘手的问题,其中的最大的问题就是组件间通信统一的状态管理。因为是有一个超级复杂的组件操作方式和组件嵌套,在做组件间通信的时候,为了保持状态的一致性,不断的将事件和属性一层一层往下传、或者往上传。真是糟糕的回忆啊....... 当时用的是Angular2。而我为了解决这个问题,写了一套基于订阅-发布模式的事件通知框架,原本想解决这些问题,结果,确实解决了组件间通讯统一状态管理的问题,但是最终带来的确实更加复杂的事件管理和更加无无序的组件关系....
  • 后来使用vue+vuex做了一些项目,反倒是突然领悟的redux的思想,就开始了第三次的学习,直到现在,我觉稍微缓解了我在前端项目所受到的伤害,redux的文档有点像上帝视角,他好像在说,我知道你应该知道的,所以我这么说你应该懂得,其实我不懂。所以我要从凡人视角说说redux扒开他的神袍,看看他的胸毛......

0x003 再说一些废话

在前面react的文章中,我一直在重复react中都是js,就是为了把思想引回react的本质,react是基于js写的一个框架而已,只是一个框架,并不是一门独立的语言。很多人总是用了jQuery就忘了原生,用了React就忘了jQuery和原生。而来了redux,就必须和react绑定。这是一个极大的思想误区,从个体上来说,vue是独立的、自由的,react也是独立的、自由的,redux也是独立的、自由的。

的确有redux在react中的最佳实践,却绝对没有redux的唯一实践这种说法,在js的世界中,各大框架各放异彩,他们既可以兼容并济,也可以相互排斥,不过就是js中的一员罢了。每个框架就像每个人一样,有自己的特点,react可以构建uiredux能够管理状态,axios在行网络,angular啥都行!你可以在vue中使用redux,也可以在vue中使用jQuery,甚至也可在你自己的项目中同时使用vuereact,语言也好,框架也罢,都是为了向伟大航线进发而服务的。

一句话总结:自由,然后秩序,接着是世间万物

0x004 订阅-发布模式

redux本质上也是基于订阅-发布模式的产物(我记得没错的话,如果记错了,之后回来改),和我写的那个小框架一样.....,所以在使用redux之前,先来研究一下这个模式,看看我之前写的那个小东西:

let eventMap = {}class MyEvent {/*** 发布一个事件并附带一份数据** @param name 发布的事件名* @param data 附带的数据*/static pub(name, data) {if (!eventMap.hasOwnProperty(name)) returnlet callbacks = eventMap[name]if (callbacks.length === 0) returncallbacks.forEach((callback) => {callback(data)})}/*** 订阅一个事件并附带一个回调* 说明这个事件发生的时候所要做的事情** @param name 订阅的事件名称* @param callback 回调* @returns {function(): *} 返回一个函数, 执行这个函数将会取消订阅*/static sub(name, callback) {let callbacks = []if (eventMap.hasOwnProperty(name)) {callbacks = eventMap[name]}callbacks.push(callback)eventMap[name] = callbacksreturn () => callbacks.shift(callback)}}export default MyEvent

这个库一共只有两个接口:

  • pub(name:String,data:data):void:发布一个事件,这个事件附带一些数据,当这个事件发布的时候,所有订阅这个事件的都将会收到通知,并执行订阅这个事件的时候定义的操作,即回调函数。
  • sub(name:String,callback:Function):Fuction:订阅一个事件,当这个事件发生的时候,即调用pub的时候,该callback就会执行,并且在callback中可以收到这个事件发生的时候的附带数据。该函数还返回一个新的函数,调用这个函数可以取消订阅该事件

案例:

import MyEvent from '../../0x012-component-communication/src/MyEvent'// 定义一个变量
let num = 1
// 定义一个事件名
const EVENT_INCREMENT = 'EVENT_INCREMENT'// 订阅这个事件,并将取消订阅的函数保存起来
let unSub = MyEvent.sub(EVENT_INCREMENT, (data) => {console.log(data)
})
// 当 num 发生变化的时候,发布这个时间
num += 1
MyEvent.pub(EVENT_INCREMENT, {num: num})// 当 num 发生变化的时候,发布这个时间
num += 1
MyEvent.pub(EVENT_INCREMENT, {num: num})// 取消订阅
unSub()// 当 num 发生变化的时候,发布这个时间
num += 1
MyEvent.pub(EVENT_INCREMENT, {num: num})
// 当 num 发生变化的时候,发布这个时间
num += 1
MyEvent.pub(EVENT_INCREMENT, {num: num})
console.log({num})

查看浏览器,可以看到,我们收到了两次通知,因为我们在中途取消了订阅

原理就是保存了MyEvent中的eventMap保存了一个Map,该Map是一个String=>Array<Function>,当我们订阅事件的时候,即调用sub的时候,就会形成如下的数据结构:

name                 |    callbacks
EVENT_INCRECEMENT    |    (data)=>{...}
-                    |    (data)=>{...}
-                    |    (data)=>{...}
EVENT_DECRECEMENT    |    (data)=>{...}
-                    |    (data)=>{...}

当我们调用pub的时候,就或寻找到这个事件名,并循环将该事件名下挂载的callback队列执行。
当我们调用unsub的时候,则会将这个callback从队列中移除,这样就不会执行了。

redux的原理和这个简陋的框架类似,就是比这精巧多了,不过本质还是一样的,我们可以订阅某个值的变化,然后在某个值变化并收到这个通知的时候作出我们自己的逻辑。

接下来我们会使用redux,然后通过redux来改造这个我们的ledux,打造成至少表面上类似的......

0x005 redux栗子

import {createStore} from 'redux'// 定义一个 reducer
function counter(state = 0, action) {switch (action.type) {case 'INCREMENT':return state + 1case 'DECREMENT':return state - 1default:return state}
}// 定义一个store,持有全局的 state
let store = createStore(counter)// 订阅,并输出 state
store.subscribe(() =>console.log(store.getState())
)
// 发布一个事件
store.dispatch({type: 'INCREMENT'})
store.dispatch({type: 'INCREMENT'})
store.dispatch({type: 'DECREMENT'})

查看浏览器

可以看到,其实模式差不多:

  • 定义数据:

    • redux:reducer 部分
    • MyEvent:let num部分
  • 订阅:

    • redux:subscribe 部分
    • MyEvent:sub部分
  • 发布:

    • redux:dispatch 部分
    • MyEvent:pub部分

但是其实内部差别又非常大,在MyEvent中,都是很随意的,我可以随便定义事件,随便修改数据,随便发布事件,所以我写的东西叫做事件通知,而不是状态管理。redux是用来做状态管理的,可以说是在事件通知之中再一次做了封装。

  • MyEvent中数据是可以随意修改的,但是在redux中,数据的修改只能通过dispatch提交一个修改请求,而在reducer中处理这个请求。

0x006 ledux实现:

  • 编写redux
class Ledux {static createStore(reduer) {return new Store(reduer)}
}class Store {constructor(reducer) {this.state = reducer(null, {})this.callbacks = []this.reducer = reducer}subscribe(callback) {this.callbacks.push(callback)}getState() {return this.state}dispatch(action) {this.state = this.reducer(this.state, action)this.callbacks.forEach(callback => callback())}}export default Ledux
  • 使用Ledix

import Ledux from "./ledux";function counter(state = 0, action) {switch (action.type) {case 'INCREMENT':return state + 1case 'DECREMENT':return state - 1default:return state}
}
let store=Ledux.createStore(counter)store.subscribe(()=>{console.log(store.getState())
})store.dispatch({type: 'INCREMENT'})
store.dispatch({type: 'INCREMENT'})
store.dispatch({type: 'DECREMENT'})
  • 查看浏览器

可以看到,效果是一样的,而过程除了我喜欢用class封装以外也没有太大的区别,就这样实现了ledux了,当然随着对reduxapi的深入学习,这个框架也可以不断的深入发展。

0x007 资源

  • 源码

Redux入门0x101: 简介及`redux`简单实现相关推荐

  1. Redux 入门教程(一):基本用法

    一年半前,我写了<React 入门实例教程>,介绍了 React 的基本用法. React 只是 DOM 的一个抽象层,并不是 Web 应用的完整解决方案.有两个方面,它没涉及. 代码结构 ...

  2. redux 入门到实践

    前言 之前没太理解redux,在使用时总是照葫芦画瓢,看项目里别人如何使用,自己就如何使用,这一次彻底学习了下官方文档,记录. 在学习redux初时,有三个概念需要了解. action reducer ...

  3. Redux简介以及Redux应用程序中的状态更新方式

    by Syeda Aimen Batool 通过Syeda Aimen Batool Redux简介以及Redux应用程序中的状态更新方式 (An intro to Redux and how sta ...

  4. Redux技术架构简介

    Redux是一个程序架构,源于Flux(Facebook提出的一种架构),然而,它不仅可以应用于React,还可以应用于其他任何框架中.值得一提的是,Redux的源代码很少,但是他的逻辑拆分和函数式编 ...

  5. redux入门_Redux入门

    redux入门 典型的Web应用程序通常由几个共享数据的UI组件组成. 通常,多个组件的任务是显示同一对象的不同属性. 该对象表示可以随时更改的状态. 在多个组件之间保持状态一致可能是一场噩梦,尤其是 ...

  6. React Redux入门

    目录 入门 我们应该什么时候使用? Redux库和工具 Redux Toolkit Redux DevTools 扩展 demo练习准备工作: 基础示例 Redux Toolkit示例 Redux术语 ...

  7. Redux入门之实现一个迷你版的Redux

    Redux是一种数据架构模式,它可以用来管理应用的状态. 之前一直在做Angular的项目,没有使用到过Redux,对于Redux的使用场景和原理都不是很清楚,看资料时作者自己实现了一个Redux,在 ...

  8. Redux系列01:从一个简单例子了解action、store、reducer

    先看例子 其实,redux的核心概念就是store.action.reducer,从调用关系来看如下所示 store.dispatch(action) --> reducer(state, ac ...

  9. 初学redux笔记,及一个最简单的redux实例

    categories: 笔记 tags: react redux 前端框架 把初学redux的一些笔记写了下来 分享一个入学redux很合适的demo, 用redux实现计数器 这是从阮一峰老师git ...

最新文章

  1. 关于假冒网站仿冒网易云信官网相关情况的声明
  2. python执行linux和window的命令
  3. Udp通讯(零基础)
  4. 玩游戏计算机丢失msvcp,Win10系统玩吃鸡提示游戏缺少msvcp140.dll的解决方法
  5. 表单和ajax中的post请求后台获取数据方法
  6. 转贴:水晶报表动态加载图片(签名)
  7. pp助手|pp助手下载
  8. log10/log2--求常用对数/以2为底的对数
  9. 计算机网络的地址三类,计算机网络中有几种地址格式
  10. KM3模拟键盘鼠标模块使用说明---2.键盘功能
  11. python 游戏引擎 cocos2d_2.2 完成一个Cocos2d游戏程序代码
  12. 苹果iOS/iPadOS 15.2 Beta 1发布 app隐私报告?
  13. ADsAD合辑(二)AD具体使用
  14. 最接近win7的Linux系统,Win7的优势所在 - Ubuntu PK Win7旗舰版到底还差多少火候_Linux新闻_Linux公社-Linux系统门户网站...
  15. 使用acmesh免费开启https(详细概念介绍与操作步骤记录)
  16. 【EasyClick iOS免越狱常见问题】iPhone重启后无法启动代理程序
  17. 5.Python之input和while
  18. 将“碳中和”融入企业发展,经济学人集团制订“双25”减排计划
  19. 动态建立Vxlan隧道实现跨子网互访实验配置(分布式网关单租户多子网场景)
  20. Google发布Google Trends(谷歌趋势)中文版

热门文章

  1. 罗马复兴各民族兵种详细参数——巴比伦篇
  2. LDAP和AD的关系 LDAP和Active Directory的区别
  3. 互联网日报 | 唯品会连续32个季度盈利;微信及WeChat月活跃帐户12.1亿;美团旗下小象生鲜停用...
  4. 如何获取csgo中的所有皮肤?
  5. 多媒体计算机辅助教学与课件制作,多媒体教学课件制作的基本要求是什么
  6. Python日期格式
  7. 为什么支付宝使用用户体验欠佳的安全控件,而国外 Paypal、Google Checkout 都没有这种的设计?...
  8. vue注册全局方法:生成单号------年月日(4+2+2)+随机数n位 (前端生成单号,从接口取单号)
  9. vue+springboot保存头像
  10. vuetifyjs文本域输入实时保存