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. jquery源码解析:jQuery队列操作queue方法实现的原理

    我们先来看一下jQuery中有关队列操作的方法集: 从上图可以看出,既有静态方法,又有实例方法.queue方法,相当于数组中的push操作.dequeue相当于数组的shift操作.举个例子: fun ...

  2. SQL查询表结构的语句

    SELECT tableName=CASE WHEN a.colorder=1 THEN d.name ELSE '' END ,表说明 =CASE WHEN a.colorder=1 THEN IS ...

  3. SSM搭建

    SSM搭建 SSM(Spring+SpringMVC+MyBatis)框架集由Spring.SpringMVC.MyBatis三个开源框架整合而成,常作为数据源较简单的web项目的框架.. Sprin ...

  4. eclipse安装SonarLint插件,sonarLint客户端的使用

    一.在线安装sonarLint 打开eclipse里的help->Eclipse Marketplace,搜索“sonar”关键字,目前sonar的插件是sonarlint,如下图: 点击“In ...

  5. python中type、class、object的区别

    type 一. type可以用来返回一个对象的类型 例如: 二. 由于Python中一切皆对象,也就是说Python中的任何变量类型都是可以被修改的,这也是Python等动态编程语言的特点.type的 ...

  6. AssertJ断言系列-----------<数据库断言二>

    那么,在实际的接口测试中,我们除了要断言响应的数据正确之外,可能有的还需要断言数据层是否数据真的有入库. assertj db是可以直接对数据库进行断言和操作的. 一.创建一个students表 CR ...

  7. ltp-ddt eth过程中遇到的问题

    eth_iperf_tcp ETH_S_PERF_IPERF_TCP_INTPACING_8K_1448B source 'common.sh'; iface=`get_eth_iface_name. ...

  8. js 的概念和声明-js 的变量-js 的运算符和逻辑结构-js 的数组

    js 的概念和声明Js的概念和声明:问题:在网页的发展历程中,发现网页不能对用户的数据进行自动校验,和提供一些特效造成用户体验极差解决:使用JavaScript作用:可以让网页和用户之间进行直接简单的 ...

  9. Mac 10.12安装Homebrew图形化界面管理工具Cakebrew

    下载: (链接: https://pan.baidu.com/s/1mivJ9H2 密码: f8dr)

  10. C#中复制数组

    string array = new string[]{"abc", "bcd", "efg"}; string bArray = new ...