Redux的createStore实现
Redux的createStore实现
使用过react的同学应该对Redux这个东西有所了解。他是一种全局状态管理的思想(对, 这里我觉得它是一种思想, 因为对于React来说, 其实Redux内部并没有什么需要与React兼容的东西, react-redux 库里才有), 它信奉的是:
- 唯一数据仓库
- 只能读取
- 数据改变只能通过纯函数进行
这其实对我们是一种约束, 毕竟我们就算引入了Redux, 也能使用this.props
去进行父子组件数据传输, 但是当你需要非父子组件的通信的时候, 里面的数据流动会非常难以捉摸, 所以我们使用Redux。
在React中集成Redux时, 在程序的入口处,我们可以看到这样的一段代码
// 这里的todoApp是一个Reducer函数,接受的是state和actions
const store = createStore(todoApp)
在我们的react使用单一仓库的时候,能看到一下的一些类似的代码,从中我们能看到,我们本组件的state
是通过this.state = store.getState()
所创建的, 那么我们的store
是一个对象,里面有一个getState
函数能够返回内部的state
,同时这个state
是需要持久保存的,所以我们大概能有一些思路。
import React, { Component } from 'react'
import store from '../../store'
import { getIPData } from '../../store/actionCreators'
class Page extends Component {
// 我的初始化的一个组件,已经能够使用Redux了
constructor(props) {
super(props);
this.state = store.getState()
store.subscribe(this.storeChange.bind(this));
}
componentWillMount() {
// 获取IP数据,这里是作为一个dispatch的例子
// 值得注意的是getIPData()返回的是一个带type字段的一个对象。
const action = getIPData();
store.dispatch(action);
}
render() {
return (
<div className="page">
</div>
)
}
storeChange() {
this.setState(store.getState())
}
}
export default Page
接下来我将自己写的createStore
函数贴出来, 然后讲解。这个函数实现了大部分功能,但是对于中间件的处理这里并没有能够实现,后面我应该会对其有一些补充。
export default function createStore(reducer){
let state = null;
const listeners = [];
const getState = () => state
const dispatch = (action) => {
state = reducer(state, action)
listeners.forEach(listener => listener())
}
const subscribe = (listener) => listeners.push(listener)
// 这里初始化dispatch的原因是在这之前,state是为null的
//所以我需要传一个不存在的action去reducer里面,拿到最默认的那个defaultState
//这个defaultState写在reducer的那个文件里面
dispatch({});
return {
dispatch,
subscribe,
getState,
}
}
所以刚才的分析, 我们需要创建一个函数对象createStore
1、createStore
里面用闭包的方法储存了一个state
,我们程序用到的仓库就是这个、还储存有一个函数数组listeners
,用于储存用户定义的函数(一般是用更新后的仓库重置this.state
),因为我其实有多个页面都注册了一个订阅函数, 所以使用函数数组, 当需要分发时取出来取出来调用即可。
2、createStore
需要定义一个方法getState
能够拿到state
,这样就能够在React中使用this.state = store.getState()
来初始化state
并进行读取了
3、createStore
还需要定义一个方法dispatch
, 因为redux不能直接修改state
的值, 所以必须通过dispatch
函数,传入action
, 然后带着state
直接传入reducer
里, reducer
会传回修改后的state
。
4、createStore
再需要定义一个方法subscribe
, 这是用来监听修改的函数, 在使用时, 绑定一个函数, 这个函数里会在外界获得state
。所以这个函数应该接收一个函数, 然后push入一个队列里, 可是应该实时监听的, 为何要置入队列呢?这里我的理解是, 在一开始就将"外界重新获得state"这个函数置入队列, 类似Promise我承诺会使用这个函数。所以这个函数的使用应该放置在dispatch
里面, 它传回一个state
后, 做的事情是将所有队列中的"外界重新获得state"函数全部拿出来执行一遍。
所以这个createStore
函数的效果很明显了,getState
用于获取当前state
, subscribe
用于给外界设置监听并将监听函数储存在createStore
函数的属性中, 每次用户通过dispatch
传action
来修改state
的时候, 将里面所有的监听函数拿出来执行一遍。而dispatch
则是用来执行state
修改的, 毕竟这个函数不允许使用setState
这类的函数。
这样, 我们就简单了解并分析了Redux的基本原理并对其进行了重写, 就像我提到的, Redux其实是一种约束的思想而出现, 这意味着在node中, 我们同样也能使用Redux(虽然我觉得可能没有必要)
Redux的createStore实现的更多相关文章
- redux之createStore方法底层封装模拟
首先在看代码之前让我们一起回顾下redux的思想吧 首先redux就是一个MVC思想的框架,他总体是遵循数据的单向流动自顶向下流动 在我们仓库中有一个initState用来存储着我们的初始数据 另 ...
- redux中createStore方法的默认参数
一般使用方法: createStore(reducer, applyMiddleware(thunk)) 传递默认参数: createStore(reducer, defaultState, appl ...
- Redux源码分析之createStore
接着前面的,我们继续,打开createStore.js, 直接看最后, createStore返回的就是一个带着5个方法的对象. return { dispatch, subscribe, getSt ...
- 实例讲解react+react-router+redux
前言 总括: 本文采用react+redux+react-router+less+es6+webpack,以实现一个简易备忘录(todolist)为例尽可能全面的讲述使用react全家桶实现一个完整应 ...
- redux介绍与入门
p.p1 { margin: 0.0px 0.0px 0.0px 0.0px; font: 20.0px Helvetica } p.p2 { margin: 0.0px 0.0px 0.0px 0. ...
- Redux介绍及基本应用
一.Redux介绍 Redux的设计思想很简单,就两句话: Web应用是一个状态机,神力与状态是一一对应的 所有的状态,保存在一个对象里面 二.Redux基本概念和API Store Store就是 ...
- redux学习笔记
中文api:http://cn.redux.js.org/docs/react-redux/troubleshooting.html 3.6 Reducer Store 收到 Action 以后,必须 ...
- 深入Redux架构
关于redux 之前写了一篇通过一个demo了解Redux,但对于redux的核心方法没有进行深入剖析,在此重新总结学习,完整的代码看这里.(参考了React 技术栈系列教程) 什么情况需要用redu ...
- 【前端】react and redux教程学习实践,浅显易懂的实践学习方法。
前言 前几天,我在博文[前端]一步一步使用webpack+react+scss脚手架重构项目 中搭建了一个react开发环境.然而在实际的开发过程中,或者是在对源码的理解中,感受到react中用的最多 ...
随机推荐
- 吴裕雄--天生自然python学习笔记:Python3 输入和输出
输出格式美化 Python两种输出值的方式: 表达式语句和 print() 函数. 第三种方式是使用文件对象的 write() 方法,标准输出文件可以用 sys.stdout 引用. 如果你希望输出的 ...
- C\C++ 位域操作
几篇较全面的位域相关的文章: http://www.uplook.cn/blog/9/93362/ C/C++位域(Bit-fields)之我见 C中的位域与大小端问题 内存对齐全攻略–涉及位域的内存 ...
- IOUtils和FileUtils的学习笔记
pom文件导入依赖import org.apache.commons.io.FileUtils; <dependency> <groupId>commons-io</gr ...
- Luogu_2279_[HNOI2003]消防局的设立
题目描述 2020年,人类在火星上建立了一个庞大的基地群,总共有n个基地.起初为了节约材料,人类只修建了n-1条道路来连接这些基地,并且每两个基地都能够通过道路到达,所以所有的基地形成了一个巨大的树状 ...
- Python---11模块
在计算机程序的开发过程中,随着程序代码越写越多,在一个文件里代码就会越来越长,越来越不容易维护. 为了编写可维护的代码,我们把很多函数分组,分别放到不同的文件里,这样,每个文件包含的代码就相对较少,很 ...
- JavaScript值类型和引用类型有哪些
JavaScript值类型和引用类型有哪些 (1)值类型:数值.布尔值.null.undefined. (2)引用类型:对象.数组.函数.
- Golang: chan定义问题(7)
通常都是定义读写双向的 chan,定义单向 chan 问题. 专栏的介绍可以参考 <GotchaGolang专栏>,代码可以看<宝库-Gotcha>. 通过 只写 chan 传 ...
- docker学习读书笔记-一期-整理
0.Docker - 第零章:前言 1.Docker - 第一章:Docker简介 2.Docker - 第二章:第一个Docker应用 3.Docker - 第三章:Docker常用命令 4.Doc ...
- acedCommandS 实现pedit命令
acedCommandS(RTSTR, _T("PEDIT"), RTSTR, _T("M"), R ...
- 使用python抓取汽车之家车型数据
import requests import pymysql HOSTNAME = '127.0.0.1' USERNAME = 'root' PASSWORD = 'zyndev' DATABASE ...