react使用redux做状态管理,实现多个组件之间的信息共享,解决了父子组件、兄弟组件之间的复杂通信问题。vue有vuex,总之是一种flux的思想。react提供了react-redux这个库,一看名字就知道是为了将react和redux关联起来,react-redux有connect高阶函数以及Provider组件、milddleware、thunk等,来实现一下。

篇幅过长,多分了几篇。

1. Redux简单实现


这里先不考虑中间件机制

import { createStore } from 'redux'

function counter(state = 10, action) {
console.log(state, action)
switch (action.type) {
case 'add':
return state + 1
case 'less':
return state - 1
default:
return state
}
} const store = createStore(counter) const init = store.getState()
console.log(`Init count: ${init}`) function listener(){
const current = store.getState()
console.log(`count: ${current}`)
}
store.subscribe(listener) store.dispatch({ type: 'add' })
store.dispatch({ type: 'less' })

这是redux简单的例子,首先我们定义了一个reducer叫做counter,接下来使用redux提供的createStore方法将reducer传入,构造出了一个store,然后基于观察者模式,触发相应的action,进行相应的响应。

Redux重点的方法就是createStore、getState、subscribe、dispatch这四个方法。大体讲一下思路,我们的Redux,这里就叫myRedux,myRedux和Redux一样,都是只暴露出来一个方法,那就是createStore,然后createStore保存着一个state,可以是对象、字符串、数组等,可以通过getState方法来访问state,还有对state的监听器以及订阅的方法,实现一下。

export function createStore (reducer) {
let state = {}
let listeners = [] function getState () {
return state
}
function subscribe (listener) {
listeners.push(listener)
}
function dispatch (action) {
state = reducer(state, action)
listeners.forEach(listener => listener())
return action
}
// 为了确保createStore之后,store.getState中就有state的初始值
dispatch({type: '@myRedux/qwe'})
return {getState, subscribe, dispatch}
}

其实就是一个观察者模式,值得注意的是:当执行完createStore之后,执行stroe.getState方法就能获取到初始的状态(我们这里是10),所以需要我们的reducer先执行一次,那么我们就要在createStore中就先dispatch一下,代码中有体现。Redux中也是这么做的,Redux初始化dispatch的type值是@@redux/INIT,可以看一下。

这么做是为了确保初始化dispatch的type值不会和用户定义的type值重复,我们代码里type为@myRedux/qwe

2.react中的context


要理解react-redux原理,必须先说下react中的context。父组件向子组件传递数据,可以通过props,如果层级比较深呢?就不好了,会有性能问题,我们可以通过context来实现跨级传递数据。

context是全局的,在组件中声明,所有的子组件都可以获取到context,react觉得全局不是很安全,所以要求context都是强数据类型,即任何想访问context里面的属性的组件都必须指定一个contextTypes的属性,如果没有指定该属性的话,用this.context访该属性就会出错。

同样,通过getChildContext方法指定传递给子组件的属性也需要被指定数据类型,通过childContextTypes来指定,不指定同样会产生错误。

下面是一个简单例子。

import React from 'react'
import PropTypes from 'prop-types' class Son extends React.Component{
render(){
return (
<div>
<p>子组件</p>
<GrandSon/>
</div>
)
}
} class GrandSon extends React.Component{
static contextTypes = {
user:PropTypes.string
}
render(){
console.log(this.context)
return (
<div>
<p>孙组件</p>
<div>孙组件收到来自父组件的信息:{this.context.user}</div>
</div>
)
}
} class Father extends React.Component{
static childContextTypes = {
user:PropTypes.string
}
constructor(props){
super(props)
this.state = {user:'user12'}
}
getChildContext(){
return this.state
}
render(){
return (
<div>
<p>父组件,要给孙组件:{this.state.user}</p>
<Son/>
</div>
)
}
} export default Father

在这里就不需要通过props一层一层的往下传递属性了,这就是context。

3.Provider组件


那么context和我们的react-redux有什么关系呢,用过的都知道,Provider组件在整个应用组件上包了一层,让整个应用组件成为Provider的子组件,看到这里,你是不是有点懂了,跟上面的例子很像嘛,对的,就是这样,我们的Provider组件接收Redux的store作为props,通过context对象传递给子组件。

我们下一篇就会说道Provider组件。

Redux和React-Redux的实现(一):Redux的实现和context的更多相关文章

  1. react+redux教程(八)连接数据库的redux程序

    前面所有的教程都是解读官方的示例代码,是时候我们自己写个连接数据库的redux程序了! 例子 这个例子代码,是我自己写的程序,一个非常简单的todo,但是包含了redux插件的用法,中间件的用法,连接 ...

  2. react系列(四)Redux基本概念和使用

    Redux基本概念和使用 先从Flux开始 先放一个Flux官网的链接.需要fq. Flux是Facebook提出的一种构建客户端网页应用的应用架构,它是一种抽象程度很高的设计模式,鼓励单向数据流. ...

  3. React:快速上手(5)——掌握Redux(2)

    React:快速上手(5)——掌握Redux(2) 本文部分内容参考阮一峰的Redux教程. React-Redux原理 React-Redux运行机制 我觉得这张图清楚地描述React-Redux的 ...

  4. React:快速上手(4)——掌握Redux(1)

    React:快速上手(4)——掌握Redux 引入Redux 混乱的state管理 随着 JavaScript 单页应用开发日趋复杂,JavaScript 需要管理比任何时候都要多的 state (状 ...

  5. 理解 React,但不理解 Redux,该如何通俗易懂的理解 Redux?

    作者:Wang Namelos链接:https://www.zhihu.com/question/41312576/answer/90782136来源:知乎著作权归作者所有.商业转载请联系作者获得授权 ...

  6. 理解 React,但不理解 Redux,该如何通俗易懂的理解 Redux?(转)

    作者:Wang Namelos 链接:https://www.zhihu.com/question/41312576/answer/90782136来源:知乎 解答这个问题并不困难:唯一的要求是你熟悉 ...

  7. Redux 和React 结合

    当Redux 和React 相接合,就是使用Redux进行状态管理,使用React 开发页面UI.相比传统的html, 使用React 开发页面,确实带来了很多好处,组件化,代码复用,但是和Redux ...

  8. redux在react项目中的应用

    今天想跟大家分享一下redux在react项目中的简单使用 1 1.redux使用相关的安装 yarn add redux yarn add react-redux(连接react和redux) 2. ...

  9. 使用Redux管理React数据流要点浅析

    在图中,使用Redux管理React数据流的过程如图所示,Store作为唯一的state树,管理所有组件的state.组件所有的行为通过Actions来触发,然后Action更新Store中的stat ...

  10. react项目中引入了redux后js控制路由跳转方案

    如果你的项目中并没有用到redux,那本文你可以忽略 问题引入 纯粹的单页面react应用中,通过this.props.history.push('/list')就可以进行路由跳转,但是加上了redu ...

随机推荐

  1. 文件操作示例脚本 tcl

    linux 下,经常会对用到文件操作,下面是一个用 tcl 写的文件操作示例脚本: 其中 set f01 [open "fix.tcl" w] 命令表示 打开或者新建一个文件“fi ...

  2. linux 缓存手动清除

    linux下怎么清理缓存 free -m 命令可以查看内存使用情况                   sysctl 命令可以临时改变某个系统参数  如:sysctl -w net.ipv4.ip_f ...

  3. 实现Redis Cluster并实现Python链接集群

    目录 一.Redis Cluster简单介绍 二.背景 三.环境准备 3.1 主机环境 3.2 主机规划 四.部署Redis 4.1 安装Redis软件 4.2 编辑Redis配置文件 4.3 启动R ...

  4. C++练习 | 计算两日期之间天数差

    #include<iostream> #include<string> #include<cstring> using namespace std; class D ...

  5. jQuery----初识jQuery

    一.jQuery好处: ①写得少,做的多 ②链式编程 ③隐式迭代 ④解决兼容性问题 二.顶级对象 Dom中的顶级对象:document------>页面中的顶级对象 document.点出来的是 ...

  6. 利用phar实行php反序列化命令执行(测试环境复现)

    测试环境的过程大概是:构成出来的phar文件,并修改为任意后缀上传至服务器.通过index.php中存在的文件操作函数参数可控,把参数设置为 phar://上传文件名 即可导致命令执行. index. ...

  7. #leetcode刷题之路18-四数之和

    给定一个包含 n 个整数的数组 nums 和一个目标值 target,判断 nums 中是否存在四个元素 a,b,c 和 d ,使得 a + b + c + d 的值与 target 相等?找出所有满 ...

  8. 时间序列分析工具箱——tidyquant

    目录 时间序列分析工具箱--tidyquant tidyquant 的用途 加载包 tq_get:获得数据 从 Yahoo! Finance 获得股票数据 从 FRED 获得经济数据 使用 tq_tr ...

  9. JavaScript总结(二)

    JavaScript的数据类型 ✍ 原始数据类型值: JavaScript有5中原始数据类型,通过调用typeof运算符返回值查看变量类型: ➣ Undefined ➔ 'undefined': Un ...

  10. PostgreSQL的索引膨胀

    磨砺技术珠矶,践行数据之道,追求卓越价值 回到上一级页面:PostgreSQL内部结构与源代码研究索引页    回到顶级页面:PostgreSQL索引页 索引膨胀,主要是针对B-tree而言. 索引膨 ...