redux基本概念

基本概念

1.store
用来保存数据的地方,使用createStore来生成数据
store = createStore(fn) 2.state,通过拷贝store中的数据得到
state = store.getState() 3.action,用来表示视图发生的变化
action = {
type:'ADD_TODO',
payload:'Learn Redux'
} 4.Action Creator 用来生成action
const ADD_TODO = '添加 TODO' function addTodo(text){
return {
type:ADD_TODO,
text
}
} 5.dispatch 用来发出action
store.dispatch(addTodo('Learn Redux')); 6.reducer 用来处理action,返回新的state
const reducer = function(state,action){
return new_state
}

createStore

function createStore(reducer,initState,enhancer){

    //0.接收state,添加观察者
let state = initState
let listeners = [] //1. 获取state
function getState(){
return JSON.parse(JSON.stringify(state))
} //2.造一个dispatch来发送action
function dispatch(action){
state = reducer(state,action)
listeners.forEach(linstener => linstener())
} //3.添加订阅者
function subscribe(listener){
listeners.push(listener)
return function(){
listeners.filter(item => item != listener)
}
} return {
getState,
dispatch,
subscribe
}
}

combineReducer

//先拿到reducer
function combineReducer(reducer){
//把state和action交给reducer处理
return (state={},action) => (
//拿到对应reducer的处理结果在把原来的属性拷贝到新对象上
Object.keys(reducer).reduce((cur,key) => {
cur[key] = reducer[key](state[key],action)
return cur
},{})
)
}

bindActionsCreators

function bindActionsCreators(actions,dispatch){
//先拿到actions和dispatch
return Object.keys(actions).reduce((obj,key)=>{
obj[key] = function(){
//等执行的时候在调用真正的actions和dispatch
dispatch(actions[key].apply(null,arguments))
}
return obj
},{})
}

ApplyMiddleware

1.在action之后redecer处理之前

中间件的执行过程

const middleware (dispatch) => (
(action) => {
console.log('middleware')
dispatch(action)
console.log('after middleware')
}
) const middleware1 (dispatch) => (
(action) => {
console.log('middleware1')
dispatch(action)
console.log('after middleware1')
}
) // middleware -> middleware1 -> action -> middleware1 -> middleware

compose函数的虹吸现象

//先执行栈顶的middleware然后回流到栈底的middleware
const compose = (middlewares) => (
middlewares.reduce((a,b) => (
(...args) => a(b(...args))
))
)

中间件的实现

const middleware1 = dispatch => (
action => {
console.log('middleware1')
let res = dispatch(action)
console.log('after middleware1')
return res
}
)
const middleware2 = dispatch => (
action => {
console.log('middleware2')
let res = dispatch(action)
console.log('after middleware2')
return res
}
) const middleware3 = dispatch => (
action => {
console.log('middleware3')
let res = dispatch(action)
console.log('after middleware3')
return res
}
) let middlewares = [middleware1,middleware2,middleware3] const compose = middlewares => middlewares.reduce((a,b) => (
(...args) => a(b(...args))
)) const dispatch = (action) => {
console.log(`action: ${action}`)
return action
} //这是最后一个中间件,调用它将返回第一个中间件
const afterDispatch = compose(middlewares)(dispatch) const testAction = args => ({
type:"ACTION_TEST",
args
}) afterDispatch(testAction('plus!'))

applyMiddleware

const compose = middlewares => middlewares.reduce((a,b) => (
(...args) => a(b(...args))
)) //1.接收中间件
export default function applyMiddleware(...middlewares){
//2.接收store方法
return function(createStore){
//3.接收reducer
return function(reducer){
let store = createStore(reducer)
let dispatch
let middlewareAPI = {
getState:store.getState,
dispatch:action => dispatch(action)
}
//把state和dispatch方法传给中间件的一个函数
middlewares = middlewares.map(middleware => middleware(middlewareAPI))
//将dispatch传入中间件,把dispatch传给最后一个中间件,把最后一个中间件的第2个函数传给上一个函数,虹吸
dispatch = compose(...middlewares)(store.dispatch)
return {
...store,
dispatch //先执行middleware1
}
}
}
}

react-redux

Provider

class Provider extends React.Component{
//静态属性childContextTypes声明提供给子组件的Context对象的属性,并实现一个实例getChildContext方法,返回一个代表Context的纯对象 (plain object) 。
static childContextTypes = {
store:propTypes.object.isRequired
}
getChildContext(){
return {
store:this.props.store
}
}
render(){
return this.props.children
}
}

Connect

function Connect(mapStateToProps,mapDispatchToProps){
return function(WrapedComponent){
class ProxyComponent extends React.Component {
//子组件需要通过一个静态属性contextTypes声明后,才能访问父组件Context对象的属性,否则,即使属性名没写错,拿到的对象也是undefined。
static contextTypes = {
store:propTypes.object
}
constructor(props,context){
super(props,context)
this.store = context.store
//初始化state
this.state = mapStateToProps(
this.store.getState()
)
}
componentWillMount(){
//当state发生变化的时候通过setState更新组件的变化
this.unsubscribe = this.store.subscribe(()=>{
this.setState(mapStateToProps(this.store.getState()));
});
}
componentWillUnmount(){
//当组件删除的时候取消监听state的变化
this.unsubscribe();
}
render(){
let actions = {}
if(typeof mapDispatchToProps == 'function'){
actions = mapDispatchToProps(this.store.disaptch);
}else if(typeof mapDispatchToProps == 'object'){
actions = bindActionCreators(mapDispatchToProps,this.store.dispatch);
}
return <WrapedComponent {...this.state} {...actions}/>
}
}
return ProxyComponent
}
}

redux实现原理的更多相关文章

  1. 轻松理解Redux原理及工作流程

    轻松理解Redux原理及工作流程 Redux由Dan Abramov在2015年创建的科技术语.是受2014年Facebook的Flux架构以及函数式编程语言Elm启发.很快,Redux因其简单易学体 ...

  2. redux原理

    Redux实现原理 不同组件需要依赖同一个数据的时候,就需要状态提升至这些组件的根组件. redux是状态统一管理工具,需要使用它的原因是: 组件之间通信统一管理,方便代码维护. React中有一个特 ...

  3. 一起学习造轮子(二):从零开始写一个Redux

    本文是一起学习造轮子系列的第二篇,本篇我们将从零开始写一个小巧完整的Redux,本系列文章将会选取一些前端比较经典的轮子进行源码分析,并且从零开始逐步实现,本系列将会学习Promises/A+,Red ...

  4. 揭开redux,react-redux的神秘面纱

    16年开始使用react-redux,迄今也已两年多.这时候再来阅读和读懂redux/react-redux源码,虽已没有当初的新鲜感,但依然觉得略有收获.把要点简单写下来,一方面供感兴趣的读者参考, ...

  5. 借鉴redux,实现一个react状态管理方案

    react状态管理方案有很多,其中最简单的最常用的是redux. redux实现 redux做状态管理,是利用reducer和action实现的state的更新. 如果想要用redux,需要几个步骤 ...

  6. 带着问题看redux源码

    前言 作为前端状态管理器,这个比较跨时代的工具库redux有很多实现和思想值得我们思考.在深入源码之前,我们可以相关注下一些常见问题,这样带着问题去看实现,也能更加清晰的了解. 常见问题 大概看了下主 ...

  7. 十分钟理解Redux核心思想,过目不忘。

    白话Redux工作原理.浅显易懂. 如有纰漏或疑问,欢迎交流. Redux 约法三章 唯一数据源(state) 虽然redux中的state与react没有联系,但可以简单理解为react组件中的th ...

  8. 对 Redux 一头雾水?看完这篇就懂了

    首先,学习 Redux 可能会很困难 当你终于学会了如何使用 React,也有了自己去构建一些应用的信心,那会是一种非常棒的感觉.你学会了管理状态,一切看起来井井有条.但是,很有可能这就到了你该学习 ...

  9. react中redux的理解

    定义 redux可以看作是flux的进阶版,主要用于react中公共状态(数据)的管理 redux底层原理 redux有一个createStore方法,这个方法用户创建公共存储空间,createSto ...

随机推荐

  1. 安装openssl-devel

    安装openssl-devel 0.操作系统为 RHEL6.7 1.描述:当开发人员需要调用openssl的库文件时,需要安装openssl-devel包 2.当根目录(即挂载点为  )的利用率为10 ...

  2. JMeterPlugin性能监控

    GUI界面中的plugins manager中的jpgc-Standard set,其中共包含以下的文件: jpgc-dummy jpgc-fifo jpgc-graphs-basic jpgc-pe ...

  3. 谷歌将对欧洲 Android 设备制造商收取其应用服务费用

    简评:欧盟就谷歌违反了<反垄断法>开出天价罚单,导致谷歌运营生态被打破,为了配合这一裁决,谷歌将调整其运营模式.欧盟似乎赢了,而这最后买单的却是消费者. 今年七月份,谷歌要求 Androi ...

  4. SaltStack 基础

    介 SaltStack是基于Python开发的一套C/S架构配置管理工具.它的底层使用ZeroMQ消息队列pub/sub方式通信,使用SSL证书签发的方式进行认证管理.号称世界上最快的消息队列Zero ...

  5. 利用atimicInteger cas的特性实现一个锁

    利用atimicInteger cas的特性实现一个锁 主要是使用的是 atomicIntegerAPI 的compareAndSet()方法,让线程不在阻塞,获取不到直接失败. 我们先定义一个异常类 ...

  6. ReactNative常用组件库 react-native-camera 相机

    通过react-native-camera调用原生相机,及自定义样式 GitHub地址: https://github.com/react-native-community/react-native- ...

  7. springcloud(六)-Ribbon配置自定义算法

    前言 很多场景下,可能根据需要自定义Ribbon的配置,例如修改Ribbon的负载均衡规则等.Spring Cloud Edgware允许使用java代码或属性自定义Ribbon 的配置,两种方式等价 ...

  8. [转] flume使用(六):后台启动及日志查看

    [From] https://blog.csdn.net/maoyuanming0806/article/details/80807087 处理的问题flume 普通方式启动会有自己自动停掉的问题,这 ...

  9. js数字格式化为千分位

    方法1: 浏览器自带的一个方法 const num=12345.6789 num.toLocaleString();=>"12,345.679" 方法2: 正则匹配 func ...

  10. 关于.NET中FileSystemWatcher的一些不被人注意的细节

    .NET 中的FileSystemWatcher可以监控文件系统中的更改.新建.删除和重命名,关于它的事件及属性的讨论有许多,但细节性的具体在什么情况下触发这些事件讨论不多.根据个人测试,总结如下: ...