React-StepPitGuide
  • 封面
  • 前言
  • 基础知识
    • 环境配置
      • WebPack 前端打包工具
      • Babel 编译器
      • Node 环境配置
    • 版本说明
    • JSX
    • 组件
    • Child组件
    • 多组件嵌套
    • 组件生命周期
      • 组件生命周期(React16之前)
    • State属性
    • Props属性
    • 类组件
      • React PropTypes
      • React 可复用组件
      • React 事件与数据的双向绑定
      • React 组件DOM操作
      • React 独立组件间共享 Mixins ⚠
      • React 高阶组件(HOC)
        • 继承方式的高阶组件
        • 代理方式的高阶组件
      • React 无状态组件与PureComponent
      • React 容器组件和展示组件
      • setState
    • 函数组件
      • React 函数子组件
      • React Hook
        • useState
        • useEffect
    • 组件样式
      • CSS內联式样
      • CSS模块化
    • 受控与非受控组件
  • 进阶知识
  • React Context
  • React 顶级API
  • React Portal 传送门
  • 应用知识
    • 路由
      • React-Router2
      • React-router4
        • React-router4 结合React-Redux
    • 服务端渲染
    • 性能优化
      • React 组件优化
        • 定制shouldComponentUpdate
        • PureComponent
        • immutablejs存在的意义和使用
      • Redux性能优化
      • React同构
    • 项目应用
      • React 文件组织方式
      • React 模块接口
      • React 合并reducer
      • React 问题
  • 状态管理
    • Flux
    • Redux
      • Redux 使用
      • Redux 异步
      • Redux Chrome插件使用
      • Redux React-Redux
      • Redux applyMiddleware
      • Redux 结合React
      • Redux 自制Redux
      • Redux 自制React-Redux
      • Redux 自制thunk中间件
      • Redux 自制arr中间件
    • Mobx
      • Mobx 思想
    • RXJS
    • immutable
  • 源码思考
    • 简述
    • SimpleReact
    • 虚拟DOM
      • 虚拟DOM概念(React 16前)
      • 虚拟DOM思考(React 16前)
    • 生命周期
    • 事件
    • Fiber
      • 数据结构
      • Scheduler 调度
      • Concurrent 异步渲染
    • Hooks
      • useState
由 GitBook 提供支持
在本页
  • 配合自制React-Redux
  • applyMiddleware中间件实现
  • compose
  • compose.js
  • createStore.js

这有帮助吗?

  1. 状态管理
  2. Redux

Redux 自制Redux

上一页Redux 结合React下一页Redux 自制React-Redux

最后更新于4年前

这有帮助吗?

简版Redux基本实现

  • tyrmars-redux.js

export function createStore(reducer) {
  let currentState = {}//状态树
  let currentListeners = []//state改变后监听

  function getState() {
    return currentState
  }

  function subscribe(listener) {
    //传入函数
    currentListeners.push(listener)//放入一个监听器
  }

  function dispatch(action){
    currentState = reducer(currentState,action)
    currentListeners.forEach(v=>v())
    return action
  }

  //触发初始状态
  dispatch({type:'@TYRMARS/Mars-Redux'})

  return {getState,subscribe,dispatch}
}

测试与redux的过程分析

import {createStore} from './TYRMars-redux'

//新建数据存放点
const store = createStore(counter)

//对于reducer处理函数,参数是状态和新的aciton
function counter(state=0,action) {
  switch (aciton.type) {
    case '+':
       return state+1
    case '-':
       return state-1
    default:
      return state
  }
}

//监听state的状态
function listerner() {
  const current = store.getState()
  console.log(`num is ${current}`)
}

//订阅每一次state修改,都会执行listener
store.subscribe(listener)

//触发动作
store.dispatch({type:'+'})
store.dispatch({type:'-'})

使用上部的自制redux可以看出

  1. 使用函数createStore创建store数据点

  2. 创建Reducer。在介绍Redux的时候,我们就知道Reducer这个🈯️指的是要改变的组件,它获取state和action,生成新的state,

  3. 用subscribe监听每次修改情况

  4. dispatch执行,reducer(currentState,action)处理当前dispatch后的传入的action.type并返回给currentState处理后的state,通过currentListeners.forEach(v=>v())执行监听函数,并最后返回当前 action状态

React 中的使用

const store = createStore(counter)

function render() {
  ReactDom.render(<App store={store} />,document.getElementById('root'));
}
render();

store.subscribe(render)

简版的Redux,采用subscribe每次监听render

export function createStore(reducer) {
  let currentState = {}
  let currentListeners = []

  function getState() {
    return currentState
  }

  function subscribe(listener) {
    //传入函数
    currentListeners.push(listener)
  }

  function dispatch(action){
    currentState = reducer(currentState,action)
    currentListeners.forEach(v=>v())
    return action
  }

  //触发初始状态
  dispatch({type:'@TYRMARS/Mars-Redux'})

  return {getState,subscribe,dispatch}
}

function bindActionCreator(creator,dispatch){
  return (...args) => dispatch(creator(...args))
}

export function bindActionCreators(creators,dispatch){
  let bound = {}
  Object.keys(creators).forEach(v=>{
    let creator = creators[v]
    bound[v] = bindActionCreator(creator,dispatch)
  })
  return bound
}
  • 对于bindActionCreators的改进

export function bindActionCreators(creators,dispatch){
  return Object.keys(creators).reduce((ret,item)=>{
    ret[item] = bindActionCreator(creators[item],dispatch)
    return ret
  },{})
}

applyMiddleware中间件实现

通过之前对于applyMiddleware中间件的理解,在此我将要实现Redux中间件

实现传入一个函数

export function createStore(reducer,enhancer) {
  if(enhancer) {
    return enhancer(createStore,reducer)
  }
  let currentState = {}
  let currentListeners = []

  function getState() {
    return currentState
  }

  function subscribe(listener) {
    //传入函数
    currentListeners.push(listener)
  }

  function dispatch(action){
    currentState = reducer(currentState,action)
    currentListeners.forEach(v=>v())
    return action
  }

  //触发初始状态
  dispatch({type:'@TYRMARS/Mars-Redux'})

  return {getState,subscribe,dispatch}
}

function bindActionCreator(creator,dipatch){
  return (...args) => dispatch(creator(...args))
}

export function bindActionCreators(creators,dispatch){
  let bound = {}
  Object.keys(creators).forEach(v=>{
    let creator = creators[v]
    bound[v] = bindActionCreator(creator,dipatch)
  })
  return bound
}

export function applyMiddleWare(middleware){
   return createStore=>(...args)=>{
      //生成原生的store
      const store = createStore(...args)
      //获取原生的dispatch
      let dispatch = store.dispatch
      //生成一个中间件的API
      const midApi = {
        getState:store.getState,
        dispatch:(...args)=>dispatch(...args)
      }
      dispatch = middleware(midApi)(store.dispatch)(action)
      // middleware(midApi)(store.dispatch)(action)
      return {
        ...store,
        dispatch
      }
   }
}

compose

compose.js

// compose(fn1,fn2,fn3)
// fn1(fn2(fn3))
export function compose(...funcs){
  if (funcs.length === 0) {
    return arg=>arg
  }
  if (funcs.length === 1) {
    return funcs[0]
  }
  return funcs.reduce((ret,item) => (...args) => ret(item(...args)))
}

createStore.js

export function createStore(reducer,enhancer) {
  if(enhancer) {
    return enhancer(createStore,reducer)
  }
  let currentState = {}
  let currentListeners = []

  function getState() {
    return currentState
  }

  function subscribe(listener) {
    //传入函数
    currentListeners.push(listener)
  }

  function dispatch(action){
    currentState = reducer(currentState,action)
    currentListeners.forEach(v=>v())
    return action
  }

  //触发初始状态
  dispatch({type:'@TYRMARS/Mars-Redux'})

  return {getState,subscribe,dispatch}
}

function bindActionCreator(creator,dipatch){
  return (...args) => dispatch(creator(...args))
}

export function bindActionCreators(creators,dispatch){
  let bound = {}
  Object.keys(creators).forEach(v=>{
    let creator = creators[v]
    bound[v] = bindActionCreator(creator,dipatch)
  })
  return bound
}

export function applyMiddleWare(...middlewares){
   return createStore=>(...args)=>{
      //生成原生的store
      const store = createStore(...args)
      //获取原生的dispatch
      let dispatch = store.dispatch
      //生成一个中间件的API
      const midApi = {
        getState:store.getState,
        dispatch:(...args)=>disptach(...args)
      }
      const middlewareChain = middlewares.map(middleware=>middleware(midApi))
      dispatch = compose(...middlewareChain)(store.dispatch)
      //dispatch = middleware(midApi)(store.dispatch)(action)
      // middleware(midApi)(store.dispatch)(action)
      // middlewares.map
      return {
        ...store,
        dispatch
      }
   }
   // middlewares.map...
}

配合

自制React-Redux