把redux当做观察者单独使用
提到redux大家肯定会想到react,但是redux这个库可以单独使用,下面我们就来看看如何把redux当做一个观察者来使用。
我们知道在观察者模式中,观察者对象一般会有两个方法,一个用来监听事件,一个用来发布消息,另外其内部一般有一个不可以见的属性来存储事件,这个属性通常为一个数组。redux会将生成一个store对象,这个对象可以理解为是一个观察者,只不过其内部保存了像树一样的数据结构,而更改数据结构,和更改产生的后果就借鉴了观察者模式。
首先来看下代码:
// 1、引入redux,导出creatStore
import { createStore } from 'redux';
// 2、设置初始值
const obj = { name: 'zs', age: 14 }
// 3、编写reduxer,传入初始值
const objReducer = (state = obj, action) => {
switch (action.type) {
case 'addage':
state.age = action.payload.age;
return {...state};
default:
return state
}
}
// 3、调用createStore生成store
const store = createStore(objReducer)
console.log(store);
// 4、调用store的subscribe方法监听事件
store.subscribe((e)=>{
console.log("disptach")
console.log(e)
})
// 5、使用store的dispatch方法触发事件,并传入action
store.dispatch({type:'addage',payload:{age:200}})
// 6、调用store.getState方法获取store树的值
console.log(store.getState());
执行上面代码我们发现,dispatch就相当于观察者的发布消息,subxcrible就相当于订阅监听事件的方法。
简单的使用redux的话,有如下几个步骤:
1、导入redux,并导出createstore方法
2、创建reducer
3、调用createstore传入reducer穿件store
4、用store的subscribe方法监听事件,用dispatch方法更改store触发事件
需要注意的是,我们在调用disptach的时候需要传递一个名为action的对象,对象有两个属性type,store通过type判断修改store树的那个数据,payload为修改时传递的参数。
上面的代码是有点需要优化的,我们在开发时,store往往比较复杂,我们需要将不同的状态保存到不同的reducer中,而不是统一放在一起。这就需要一个方法,combineReducers,看代码:
// 1、引入redux,导出creatStore
import { createStore,combineReducers } from 'redux';
// 2、编写第一个reducer
const objReducer = (state = { name: 'zs', age: 14 }, action) => {
switch (action.type) {
case 'addage':
state.age = action.payload.age;
return {...state};
default:
return state
}
}
// 3、编写第二个reducer
const arrReducer = (state = [],action)=>{
switch (action.type) {
case 'add':
state.push(action.payload)
return [...state]
default:
return state
}
}
// 4、将所有reducer用combineReducers合并成一个reducers
const reducers = combineReducers({
objReducer,
arrReducer
})
// 5、调用createStore生成store
const store = createStore(reducers)
console.log(store);
// 6、调用store的subscribe方法监听事件
store.subscribe(()=>{
console.log("disptach")
})
// 7、使用store的dispatch方法触发事件,并传入action
store.dispatch({type:'addage',payload:{age:200}})
store.dispatch({type:'add',payload:'22222'})
// 8、调用store.getState方法获取store树的值
console.log(store.getState());
使用步骤如下:
1、引入redux,并导出createStore和combineReducers
2、编写reducers,也就是编写多个reducer,每一个reducer保存某一个数据状态
3、用combineReducer是合并reducer
4、调用createStore生成store
注意:此时如果调用getStore得到的是一个对象,这个的每个属性分别指向单独定义热reducer,如图:
了解了store的结构和配置过程,接下来了解如何使用。
通常我们用dispatch来更改store,dispatch相当于观察者模式的发布消息,那谁是监听方法呢,subscrible就是观察者模式的监听者,subscrible负责将要执行的动作收集起来,在store调用dispatch时统一执行。是不是和观察者模式很像。
在开发中通常我们使用dispatch时一般是传递一个对象,但是有时为了方便,我们通常将action作为函数的返回值,代码如下:
// 生成action的函数
function createAction(type, payload){
return {
type,
payload
}
}
// dispatch的参数是一个函数调用
store.dispatch(createAction('addage',{age:9999}))
可以看到我们先声明了一个createAction函数,其内部返回了一个标准的action。
还有一种情况是,我们需要异步执行dispatch,这里一般有两种执行方式,第一种是如果我们的数据是异步获取的,那么我们可以在获取数据后在调用dispatch,另外一种是借助插件,我们可以向dispatch传递一个函数,注意事函数,而不是函数执行,dispatch会自动先调用函数,这个函数的格式是固定的,其参为dispatch,其内部既获取了数据后又可以同步执行dispatch。我们来看下代码:
这里没有黏贴代码,直接截图来的,可以观察上图第三个红框,我们发现,在dispatch内部传递了一个函数,函数的参数为dispatch和getState,在函数内部我们用setTimeout模仿了异步。
综上所述,想要向dispatch传递函数,使其支持异步调用需要如下两个步骤:
1、引入redux-thunk
2、在调用createStore时传入插件,插件需要用applyMiddleware包装一下;
这里还有一点需要注意如何我们配置开发环境,需要获取浏览器的支持,那么我们还需要如下配置
3、用window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__或者compose包裹一下插件,代码如下:
行文至此也该结束了,总结一下:
1、首先讲了redux和观察者模式的关系
2、如何使用配置redux
3、store的数据结构,合并多个reducer
4、action的变形,可以是一个函数调用,函数内部返回action
5、结合redux-thunk,dispatch内部可以传递函数,函数内部可以执行异步操作。
以上便是单独的redux的使用了,嗯,比较麻烦,每次使用都需要这么配置。希望对你有所帮助,下篇文章聊聊redux怎么和react相结合。
- 一文读懂Python多线程
- 深入理解Python变量作用域与函数闭包
- TensorFlow从1到2 - 5 - 非专家莫入!TensorFlow实现CNN
- JetBrains Rider 破解 (ideaIU等等开发工具都通用)
- python中的小魔法(一)
- 由问题入手,步步爬出Python中赋值与拷贝的坑
- python爬取链家租房之获得每一页的房屋信息地址(持续更新)
- python使用正则表达式
- python在租房过程中的应用
- python爬虫反爬取---设置IP代理自动变换requests.get()中proxy的IP
- 【译】TensorFlow实现Batch Normalization
- 关于Python语言规范你需要知道的一些小tips
- R语言可视化——REmap(路径图)
- python面向对象
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- 告诉你一个 AtomicInteger 的惊天大秘密!
- 001--算法之"高手过招"[分治算法专题]
- 快速入门使用tikz绘制深度学习网络图
- 后端服务慢成狗?试试这 7 招!
- 高性能无锁并发框架 Disruptor,太强了!
- Spring Boot 太狠了,一口气发布了 3 个版本!
- 贷款违约预测-Task2 数据分析
- Redis 最牛实践:业务层面和运维层面优化!
- 一个 randomkey 命令导致的 Redis 事故。。
- 分布式锁(数据库、Redis、ZK)拍了拍你
- 贷款违约预测-Task3 特征工程
- 用SQL代替DSL查询ElasticSearch怎样?
- 面试造飞机:面对Redis持久化连环Call,你还顶得住吗?
- 体验spring-boot-devtools热部署,流畅且不失强大,Jrebel呢?
- 贷款诈骗 x 摸版0day + 实战预警脚本