持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第18天,点击查看活动详情
1.通常我们会如下引入
import { createStore } from 'redux'
简单设想其内部实际就是实现一个闭包,内部创建一个state,subscribtion,对外暴露getState,subscribe,dispatch,等方法操作内部state和subscribtion;
到出一个applyMiddleware 应用中间件,接收若干中间件参数,
目的加强dispatch,在dispatch调用reducer之前,依次调用每一个中间件,中间件是一个函数,初始化时会被执行两次,最后返回一个终极函数,大概这样,可以比作是洋葱级别的闭包,洋葱最内层的调用dispatch是调用外一层中间件,一层一层直到,最后我们最初的dispatch方法
function dispatch (action) {
state=reducer(state,action)
subscribtion .forEach(v=>v())
return action
}
两次执行中间件第一次,将顺序搞反,第二次又搞回来,所以最后执行顺序是爱情最初的样子。
const fun=({getStore,dispatch})=>(dispach)=>(actino){
return dispatch(action);
}
export function createStore(reducer,enhancer){
//如果有中间件,就要在dispach执行reducer之前搞一些事情,
但是createStore,依然要创建,在原理基础上增强dispatch
将createStore和reducer交给enhancer处理
if(enhancer){
从这里创建storereturn enhancer(createStore)(reducer);
}
//内部变量
let state;
//内部变量存储订阅事件
const subscribtion=[];
//dispach方法,
//1调用reducer,将当前state和action将reduce返回值赋值给内部变量
//2调用所有的订阅事件
//返回action不重要,可以返回任何东西
function dispatch (action) {
state=reducer(state,action)
subscribtion.forEach(v=>v())
return action
}
function subscribe(fn){
subscribtion .push(fn)
}
return {
store,
dispatch,
subscribe
}}
//applyMiddleware在传入时先调用了一次,这一次是返回一个可以调用两次的函数,因//为//createStore里面我们这么搞的,applyMiddleware返回值又调用两次
// enhancer(createStore)(reducer);
export applyMiddleware(...fn){
reudcer可能是多个所以...解构一下子return createStore=>...arg=>{
此时创建store
let store=createStore(...arg)
获取dispatch
let dispatch=store.dispatch
let api={
getState:store.getState,
dispatch:(...arg)=>disapch(...arg)
}
调用一下所有中间件给他们传入getState和dispatch参数,得到一个加强版的中间件数组
compile函数结果调用一下,从右往左调用一圈,顺序正常了
let chian=fn.map(item=>item(api))
合并所有的的中间件,加强版dispatch诞生,
dispatch=compile(chian)(dispatch)
}
变成洋葱模型函数里面调用函数每一层都闭包一个dispatch但是并未执行从左到右一层套一层,
funtion compile(...fn){
return fn.reduce((left,rigth)=>(arg)=>rigth(left(arg)))
}}
简单的reduce
默认值为首次初始化的值
function countReducer(store=1,action){
switch(action.type){
case "add":return store+1
case "sub":return store-1
default :return store }}
export default countReducer;
使用store
如果使用中间件要安装中间件
npm i redux-logger redux-thunk -S
import {createStore} from './store'
import reducer from './reducer'
import logger from 'redux-logger'
import thunk from 'redux-thunk'
const store=createStore(reducer,applyMiddleware(logger,thunk))