一.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