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. [Objective-C语言教程]继承(25)

    面向对象编程中最重要的概念之一是继承.继承允许根据一个类定义另一个类,这样可以更容易地创建和维护一个应用程序. 这也提供了重用代码功能和快速实现时间的机会. 在创建类时,程序员可以指定新类应该继承现有 ...

  2. Java中常用到的文件操作那些事(一)——替换doc文档模板,生成真实合同案例

    工作中,我们时常会遇到一些操作文件的操作,比如在线生成合同模板,上传/下载/解析Excel,doc文档转为pdf等操作.本文就已工作中遇到的在线生成合同为例,简要地介绍一种文档替换写法. 本文目的:给 ...

  3. asp.net图片上传代码

    前端: <form action="/ImageUpload.ashx" method="post" enctype="multipart/fo ...

  4. 响应式Web设计-一种优雅的掌上展现

    入门 flat - style (too many ad.) writeshell

  5. Django 登陆注册实现

    路由层 from django.conf.urls import url from django.contrib import admin from app01 import views urlpat ...

  6. dubbo SPI设计

    SPI 全称为 Service Provider Interface,是一种服务发现机制.SPI 的本质是将接口实现类的全限定名配置在文件中,并由服务加载器读取配置文件,加载实现类.这样可以在运行时, ...

  7. 通过CGI实现在Html页面上执行shell命令

    在mac上配置cgi(不用系统自带的apache cgi.) 安装cgi 1. brew update 2. brew install httpd24 安装完后,会有如下提示 DocumentRoot ...

  8. 一次简单的ORM调研

        对于ORM,公司一直在用轻量级的PetaPoco,PetaPoco是挺轻巧,易用性和性能都非常优秀.但也有很多的缺点,在组装复杂sql语句的时候有bug,记忆中使用orderby.sum的时候 ...

  9. redux设计到源码 --- 美团点评技术团队(转)

    https://tech.meituan.com/redux-design-code.html

  10. spring boot快速入门 5: 事务管理

    事务管理: 新增两名女生: 第一步:创建 GirlRespository package com.payease.service; import com.payease.entity.Girl; im ...