React中redux-thunk,redux-saga,monkeyingpatch,拆分reducer,合并中间件等demo

一.redux-thunk

我们通常的dispatch只能传一个对象过去,但是redux-thunk可以让我们传一个函数

其实内部原理不难,我这里准备了两个js文件,就可以代替redux-thunk

connect.js

import React,{ PureComponent } from "react"

import {StoreContext} from './context'

export function connect(mapStateToProps,mapDispachToProp){
  return function enhanceHOC(WrappedComponent){
    class EnhanceComponent extends PureComponent{
      constructor(props,context){
        super(props,context);
        this.state ={ 
          storeState:mapStateToProps(context.getState())
        }
      }
      componentDidMount(){
       this.unsubscribe =  this.context.subscribe(()=>{
          this.setState({
            storeState:mapStateToProps(this.context.getState())
          })
        })
      }
      componentWillUnmount(){
        this.unsubscribe()
      }
      render(){
        return <WrappedComponent {...this.props} 
                                 {...mapStateToProps(this.context.getState())}
                                 {...mapDispachToProp(this.context.dispatch)}  
                                 />
      }
    }
    EnhanceComponent.contextType = StoreContext
    return EnhanceComponent
  }
}

context.js

import React from 'react'

const StoreContext = React.createContext()

export{
  StoreContext
}

跟redux-thunk不同的是,我们包裹app是这样的

ReactDOM.render(
<StoreContext.Provider value={store}>
    <App/>
  </StoreContext.Provider>
,document.querySelector('#root'))

而redux-thunk是

ReactDOM.render(
  <Provider store={store}>
    <App/>
  </Provider>
,document.querySelector('#root'))

二.redux-saga
其实它和redux-thunk差不多,开发中使用最多的还是redux-thunk

它主要使用了 ES6 的 Generator(生成器)

类似这样

 //生成器函数
   function* foo(){
   yield '123'
   }
   //iterator:迭代器
   const result = foo()
   console.log(result)

   //使用迭代器
   //调用一次next就会消耗一次迭代器
   const res1 =  result.next()
   console.log(res1)
  //done表示当前迭代器有没有用完
   const res2  =result.next()
   console.log(res2)

使用redux-saga

import {takeEvery from 'redux-saga/effects'

function* mySaga(){
  yield takeEvery(FETCH_HOME_MULTDATA,fetchHomeMultidata)
  //takeLatest:依次只能监听一个对应的action
  //takeEvery:每一个都会被执行
}

export default mySaga;

三.monkeyingpatch

这就是个黑科技,在函数的基础之上进行优化:修改原有的dispatch

const next = store.dispatch
function dispatchAndLogging(action) {
  console.log("dispatch前--dispatching action:", action)
  next(action)
  console.log("dispatch后--new state:", store.getState())
}

store.dispatch = dispatchAndLogging

store.dispatch(addAction()) //addAction中返回一个对象

我们还可以封装起来

function patchLogging(store) {
  const next = store.dispatch;
  function dispatchAndLogging(action) {
    console.log("dispatch前--dispatching action:", action)
    next(action)
    console.log("dispatch后--new state:", store.getState())
  }
  store.dispatch = dispatchAndLogging
}
patchLogging(store)

还可以封装patchThunk的功能

function patchThunk(store){
  const next = store.dispatch;

  function dispatchAndThunk(action){
    if(typeof action ==="function"){
      action(store.dispatch,store.getState)
    }
    else{
      next(action)
    }
  }
  store.dispatch = dispatchAndThunk
}

patchThunk(store)

合并中间件

function ApplyMiddleware(store,middlewares){
  middlewares = middlewares.slice();
  middlewares.forEach(middleware =>{
    store.dispatch = middleware(store)
  })
}
ApplyMiddleware(store,[patchLogging,patchThunk])

四.拆分reducer
业务逻辑太多,就必须进行拆分

const initialCounterState ={
  counter:0
}

//拆分counterReducer
function counterReducer(state = initialCounterState,action){
  switch(action.type){
    case ADD_NUMBER:
      return { ...state, counter: state.counter + action.num }
    case SUB_NUMBER:
      return { ...state, counter: state.counter - action.num }
    default:
      return state
  }
}

//拆分homeReducer

const initialHomeState ={
  banners:[]
}
function homeReducer(state = initialHomeState,action){
  switch (action.type) {
    case CHANGE_BANNERS:
      return {...state,banners:action.banners}
    default:
      return state
  }
}


function reducer(state = {}, action) {
  return{
    counterInfo:counterReducer(state.counterInfo,action),
    homeInfo:homeReducer(state.homeInfo,action)
  }
}

如果去组件想要拿counter的话,state.counterInfo.counter

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值