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. SpringCloud 学习(一) :Features

    话不多说,现在在开发微服务项目,也想系统的学习一下SpringCloud,顾选择硬着头皮跟着英文官方文档学习一遍SpringCloud. 现在公司在用SpringCloud,也有很好的实践应用,加上更 ...

  2. 四层and七层负载均衡

    四层负载/七层负载 在常规运维工作中,经常会运用到负载均衡服务.负载均衡分为四层负载和七层负载,那么这两者之间有什么不同? 废话不多说,详解如下: 1.    什么是负载均衡 1)负载均衡(Load ...

  3. HTML5基础知识总结(一)

    新增的标签和属性 1.结构标签 article section aside nav header footer hgroup figure address 2.媒体标签 video audio emb ...

  4. Sql server 查看锁和Kill 死锁进程

    死锁的概念 死锁就是两个或多个会话(SPID)相互请求对方持有的锁资源,导致循环等待的情况.下面两种方法都是用来粗暴的解决死锁的. # 已知阻塞进程ID KILL ID SELECT blocking ...

  5. Fiddler设置代理后,iphone手机无法访问网络的全面解决办法

    好久不抓手机包,都有些忘记了,电脑上软件都在,原本是Fiddler4,现在已自动升级到V5. 入主题吧,首先Fiddler设置好代理,然后手机安装证书好了,设置手机代理,结果iphone无法访问网络, ...

  6. Golint的简易使用方法

    根据作者的说法: Golint is a linter for Go source code. Golint differs from gofmt. Gofmt reformats Go source ...

  7. bzoj2564 集合的面积

    Description 对于一个平面上点的集合P={(xi,yi )},定义集合P的面积F(P)为点集P的凸包的面积. 对于两个点集A和B,定义集合的和为: A+B={(xiA+xjB,yiA+yjB ...

  8. 使用bootstrap-select控件 搜索栏键入关键字动态获取后台数据

    bootstrap-select开源地址:https://github.com/silviomoreto/bootstrap-select bootstrap-select使用示例:http://si ...

  9. Codeforces Round #452 (Div. 2)

    第一次打..(太弱(+99积分是几个意思 A 题意:一堆数,只有1和2,问最多凑出多少个3. 分情况即可 #include<cstdio> int main(){ int a=0,b=0, ...

  10. ncl 函数源码 gc_inout

    转自气象家园论坛 经过不懈努力,终于找到了gc_inout函数的源代码,原来在这个文件里面!一颗赛艇 位置:/ncl_ncarg-6.5.0-src/ni/src/lib/nfpfort/sg_too ...