export const ActionTypes = {INIT:'@@redux/INIT'}
// 生成一个store,和维护这个store需要的方法
// 维护一个state,暴露dispatch(action)来驱动调用传入的reducer(oldstate,action)得到修改后的state
// 维护一个listener队列,在调用reducer(oldstate,action)后遍历调用
// 预留一个接口增强dispatch的功能(添加中间件)
// 参数:
// reducer 接受action返回next state tree的一个function
// preloadedState store生成时的初始state
// 如果通过combineReducers生成了根reducer函数,此时必须使用combineReducers相同的key
// enhancer applyMiddleware 中间件,多个中间件通过appleMiddleware()来组合
// 返回:一个Redux stroe (读取state,发送action,监听state改变)
export default function createStroe(reducer,preloadedState,enhancer){
// 入参第二参数类型是否为函数,第三个参数未定义
if(typeof preloadedState === 'function' && typeof enhancer == 'undefined'){
// 根据参数类型,判断第二参数传入的是enhancer,此时将传入的值做调整
enhancer = preloadedState;
preloadedState = undefined;
}
if(typeof enhancer !== 'undefined'){
if(typeof enhancer !== 'function'){
throw new Error('enhancer to be a function')
}
// 传入了三个参数,并且第三个参数is a function(中间件),此时执行科里化
// 先执行中间件,在调用createStore
return enhancer(createStroe)(reducer,preloadedState);
}
// 判断第一个参数是否是function
if(typeof reducer !== 'function'){
throw new Error('reducer to be a function');
}
// 参数校验成功,传入了两个参数,且参数类型也合规
let currentReducer = reducer
// 初始state
let currentState = preloadedState
// 构造监听队列
let currentListeners = []
let nextListeners = currentListeners
let isDispatching = false
function ensureCanMutateNextListeners(){
if(nextListeners == currentListeners){
// 浅拷贝监听数据
nextListeners = currentListeners.slice();
}
}
// 通过Store去读state树
function getState(){
return currentState
}
// 添加订阅监听
// 传入监听回调
// 返回一个移除监听的方法)
function subscribe(listener){
if(typeof listener !== 'function'){
throw new Error('listent to be a function')
}
let isSubscribed = true;
// 监听前后队列传递
ensureCanMutateNextListeners();
// 添加监听
nextListeners.push(listener)
return function unsubscribe(){
// 是否正在添加监听 同步锁
if(!isSubscribed){
return;
}
isSubscribed = false;
// 监听前后队列传递
ensureCanMutateNextListeners();
// 判断监听是否已经添加到将监听的队列中
const index = nextListeners.indexOf(listener);
// 已添加的要移除
nextListeners.splice(index,1);
}
}
//发送一个Action,驱动state的改变
// 参数:action,要操作的行为
// 返回:传入的action
function dispatch(action){
// 判断传入的action是否唯一个原生对象,而不是a Promise, an Observable, a thunk, or something else,
if(!isPlainObject(action)){
throw new Error(
'Actions must be plain objects'+
'Use custom middleware for async actions'
);
}
// 判断传入的action是否有type
if(typeof action.type === 'undefined'){
throw new Error(
'Actions may not have an undefined "type" property.'
);
}
// 判断正在执行(同步锁)
if(isDispatching){
throw new Error('reducers may not dispatch actions');
}
// 将当前state,和传入的action作为参数,调用reducer获取修改后的state
try{
isDispatching = true;
currentState = currentReducer(currentState,action)
}finally{
isDispatching = false
}
// 处理监听
// 传递nextListeners 到currentListeners,然后执行这些监听回调
const listeners = currentListeners = nextListeners;
for(let i = 0;i
const listener = listeners[i];
listener();
}
return action;
}
function replaceReducer(nextReducer){
if(typeof nextReducer !== 'function'){
throw new Error('Expected reducer to be a function')
}
currentReducer = nextReducer
dispatch({type:ActionTypes.INIT});
}
// 为observable/reactive库预留的交互接口。
function observable(){
const outerSubscribe = subscribe;
return{
subscribe(observer){
if(typeof observer != 'object'){
throw new TypeError('Expected the observer to be an object')
}
function observeState(){
if(observer.next){
observer.next(getState())
}
}
observeState();
const unsubscribe = outerSubscribe(observeState);
return {unsubscribe}
},
[$$observable](){
return this
}
}
}
// 调用createStore时,dispatch return initial state
dispatch({type: ActionTypes.INIT})
return{
dispatch,
subscribe,
getState,
replaceReducer,
[$$observable]: observable
}
}
// conbineReducers.js reducer组合工具类
// 将一个包含了不同的reducer函数的对象,转换成一个集合reducer函数
// 在集合reducer函数中调用每一个子reducer,将他们的结果,聚集到一个state对象中,所用的key要跟redecer
// 参数 对象(包含多个reducer属性)
// 返回了一个方法,遍历执行所有属性reducer,将每个reducer返回的state,拼装成一个state树
// 所以每次dispatch调用的render时调用的就是combination()
exprot default function combineReducers(reducers){
// 获取传入对象的key集合
const reducerKeys = Object.keys(reducers);
const finalReducers = {};
for(let i = 0;i
const key = reducerKeys[i];
// 校验传入的对象属性都有值
if(process.env.NODE_ENV !== 'production' ){
if(typeof reducers[key] === 'undefined'){
}
}
//
if(typeof reducers[key] === 'function'){
finalReducers[key] = reducers[key]
}
}
// 浅拷贝出有效的reducer属性
const finalReducerKeys = Object.keys(finalReducers);
let unexpectedKeyCache
if(process.env.NODE_ENV !== 'production'){
unexpectedKeyCache = {}
}
let shapeAssertingError
try{
// 调用finalReducers中每一个reducer的Init事件
assertReducerShape(finalReducers)
}catch(e){
shapeAssertingError = e;
}
return function combination(state = {},action){
if(shapeAssertingError)
{
throw shapeAssertingError;
}
if(process.env.NODE_ENV !== 'production'){
const warningMessage = getUNexpectedStateShapeWarningMessage(state,finalReducers,action,unexpectedKeyCache)
if(warningMessage){
}
}
let hasChanged = false;
const nextState = {}
// 遍历finalReducers,构建一个state树,以finalReducers中reducer的key为key,reduer执行生成的state为value
for(let i = 0;i
// 获取reducer的key
const key = finalReducerKeys[i];
// 获取reducer的value
const reducer = finalReducers[key];
// 从state树上根据reducer的key获取之前的state值
const previousStateForKey = state[key]
// 根据执行reducer的value得到新的state值
const nextStateForkey = reducer(previousStateForKey,action);
if(typeof nextStateForkey === 'undefined'){
throw new Error();
}
// 将得到新的state值,update到state树
nextState[key] = nextStateForkey;
hasChanged = hasChanged || nextStateForkey !== previousStateForKey
}
return hasChanged?nextState:state
}
}
// 中间件集合类
// applyMiddleware,将接受到的middleware参数装换成middleware数组
// 再转换成一个初始参数为原始dispatch的一元链式函数 dispatch = w1(w2(w3(store.dispatch)))
// 从而生成新的加强了的dispatch方法
export default function applyMiddleware(...middleware){
return(createStroe)=>(reducer,preloadedState,enhancer)=>{
const store = createStroe(reducer,preloadedState,enhancer)
let dispatch = store.dispatch
let chain = []
const middlewareAPI = {
getState:store.getState,
dispatch:(action) => dispatch(action)
}
chain = middlewares.map(middleware => middleware(middlewareAPI))
dispatch = compose(...chain)(store.dispatch)
// dispatch = w1(w2(w3(store.dispatch)))
return {
...store,
dispatch
}
}
}
// 将第一个函数调用结果做为下一个函数的参数
export default function compose(...funcs){
if(funcs.length === 0){
return arg => arg
}
if(funcs.length === 1){
return funcs[0]
}
return funcs.reduce(((a,b)=>(...args) => a(b(...args)))
}
// action生成器 bindActionCreator
function bindActionCreator(actionCreator,dispatch){
return (...args) => dispatch(actionCreator(...args))
}
// bindActionCreators
// 将一个所有属性都是action creators的对象,转换成
// 参数:
export default function bindActionCreators(actionCreators,dispatch){
const keys = Object.keys(actionCreators)
const boundActionsCreators = {}
for (let i = 0;i
const key = keys[i];
const actionCreator = actionCreators[key]
if(typeof actionCreator === 'function'){
boundActionsCreators[key] = bindActionCreator(actionCreator,dispatch);
}
}
return boundActionsCreators
}
// React-Redux redux 在react上应用的辅助工具类
// 生成一个控件,使其将createStore生成state作为store ,利用React中的Context属性
// 对Provider 添加getChildContext和childContextTypes,
// 将store 传递到其所有子控件中,以供其访问
//
// Provider createProvider
//
// Component
//
export function createProvider(storekey = 'store',subKey){
const subscrptionKey = subKey || `${storeKey}Subscription`
class Provider extends Component{
getChildContext(){
return {[storeKey]:this[storeKey],[subscrptionKey]:null}
}
constructor(props,context){
super(props,context)
this[storeKey] = props.store;
}
render(){
return Children.only(this.props.children)
}
}
Provider.prototype = {
store:storeShape.isRequired,
children:PropTypes.element.isRequired,
}
Provider.childContextTypes = {
[storeKey]: storeShape.isRequired,
[subscriptionKey]: subscriptionShape,
}
return Provider
}
//
// export default connect(mapStateToProps, mapDispatchToProps)(containerName)
// 将UI组件(只展现UI)转换成可以访问Redux API 的容器组件(处理业务逻辑,和管理数据)
// 通过Provider将createStore生成的state传递到其所有子控件后
exprot function createConnect({
//参数
connectHOC = connectAdvanced,
mapStateToPropsFactories
...
}={}){
// 函数体 返回一个函数
return function connect(mapStateToProps,mapDispatchToProps,mergeProps
// 第四个参数
{
pure = ture,
....
}
){
// 将传入的mapStateToProps作为实参,
// 通过match遍历调用mapStateToPropsFactories(数组)中对应的方法(对传入
// 的mapStateToProps做判断校验)
// 如果 mapStateToProps 为null
// wrapMapToPropsConstant(() => ({}))
// 如果 mapStateToProps 为function
// wrapMapToPropsFunc(mapStateToProps, 'mapStateToProps')
// export function wrapMapToPropsFunc(mapToProps, methodName) {
// 返回一个方法
// return function initProxySelector(dispatch, { displayName }) {
// 返回一个方法 initProxySelector (initMapStateToProps)
// 声明一个方法 proxy
// const proxy = function mapToPropsProxy(stateOrDispatch, ownProps) {
// 调用proxy 时
// dependsOnOwnProps
// 为true 执行 proxy.mapToProps(stateOrDispatch, ownProps)
// 为false 执行 proxy.mapToProps(stateOrDispatch)
// return proxy.dependsOnOwnProps
// ? proxy.mapToProps(stateOrDispatch, ownProps)
// : proxy.mapToProps(stateOrDispatch)
// }
// 给proxy添加属性 dependsOnOwnProps,标示是否有ownProps参数
// // allow detectFactoryAndVerify to get ownProps
// proxy.dependsOnOwnProps = true
// 给proxy添加属性mapToProps
// proxy.mapToProps = function detectFactoryAndVerify(stateOrDispatch, ownProps) {
// 第一次调用mapToProps时调用detectFactoryAndVerify,
// 此时拿到传入的MapStateToProps 指定给mapToProps
//
// proxy.mapToProps = mapToProps
// 判断传入的 mapToProps 的 dependsOnOwnProps属性是否为true
// proxy.dependsOnOwnProps = getDependsOnOwnProps(mapToProps)
//
// 再次调用proxy,调用的就是传入的 mapStateToProps
// let props = proxy(stateOrDispatch, ownProps)
// if (typeof props === 'function') {
// proxy.mapToProps = props
// proxy.dependsOnOwnProps = getDependsOnOwnProps(props)
// props = proxy(stateOrDispatch, ownProps)
// }
// if (process.env.NODE_ENV !== 'production')
// verifyPlainObject(props, displayName, methodName)
// 此时得到最后的要添加的props属性
// return props
// }
// 返回proxy
// return proxy
// }
// }
// 返回一个initMapStateToProps方法(该方法调用时返回proxy)
const initMapStateToProps = match(mapStateToProps,mapStateToPropsFactories,'mapStateToProps')
const initMapDispatchToProps = match(mapDispatchToProps, mapDispatchToPropsFactories, 'mapDispatchToProps')
const initMergeProps = match(mergeProps, mergePropsFactories, 'mergeProps')
// 调用connectAdvanced、
// 参数 selectorFactory 初始化每次props改变时要调用的方法(返回新的props给被嵌套的控件)
// 参数 {selector 计算需要的参数}
// HOC (Higher-order component)获取一个组件 返回一个高阶组件
return connectHOC(selectorFactory,{
// 实参
initMapStateToProps,
initMapDispatchToProps,
initMergeProps,
})
}
}
// 将传入的
function match(arg,factories,name){
for(let i = factories.length -1; i >= 0 ;i--){
const result = factories[i](arg)
if(result){
return result
}
}
return (dispatch,options)=>{
throw new Error
}
}
// connectAdvanced
export default function connectAdvanced(
// 参数 selectorFactory
// selector function集合,通过state.props.dispatch计算出新的props
// 组合参数 options.pure? pureFinalPropsSelectorFactory: impureFinalPropsSelectorFactory
//
// export default connnectAdvanced(
// (dispatch,options)=>
// (state,props)=>
// ({ thing:state.things[props.thingId],
// saveThing: fields => dispatch(actionCreators.saveThing(props.thingId,fields)),
// })
// )(YourComponent)
selectorFactory,
// options object:
{
} = {}
){
// 方法体
// 给出入的UI组件wrappedComponent 添加需要props,变成高阶组件
// 参数 基础组件
return function wrapWithConnect(WrappedComponent){
// 内部类
class Connect extends Component{
constructor(props,context){
super(props,context)
this.version = version
this.state = {}
this.renderCount = 0
this.store = props[storeKey]
this.initSelector();
this.initSubscription();
}
getChildContext(){
// 传递store
}
componentDidMount(){
//
}
componentWillReceiveProps(nextProps){
}
shouldComponentUpdate(){
}
componentWillUnmount(){
}
// 方便通过ref操作组件
getWrappedInstance(){
}
setWrappedInstance(){
}
initSelector(){
const sourceSelector = selectorFactory(this.store.dispatch,selectorFactoryOptions)
this.selector = makeSelectorStateful(sourceSelector,this.store);
// function makeSelectorStateful(sourceSelector, store) {
// // wrap the selector in an object that tracks its results between runs.
// const selector = {
// 为selector 添加run方法
// run: function runComponentSelector(props) {
// try {
// mergedProps = mergeProps(stateProps, dispatchProps, ownProps)
// const nextProps = sourceSelector(store.getState(), props)
// if (nextProps !== selector.props || selector.error) {
// selector.shouldComponentUpdate = true
// selector.props = nextProps
// selector.error = null
// }
// } catch (error) {
// selector.shouldComponentUpdate = true
// selector.error = error
// }
// }
// }
// return selector
// }
// 调用run(this.props)
// ->sourceSelector(store.getState(), props)
// ->mergedProps = mergeProps(stateProps, dispatchProps, ownProps)
// 传递属性给要封装的组件
this.selector.run(this.props)
}
initSubscription(){
this.subscription = new Subscription(this.store,parentSub,this.onStateChanged.bind(this))
}
onStateChange(){
this.selector.run(this.props)
}
render(){
return createElement(WrappedComponent,this.addExtraProps(this.selector.props))
}
}
return hoistStatics(Connect,WrappedComponent)
}
}
// 最后得到的就是新的props
// 1、connect(mapStateToProps,mapDispatchToProps,mergeProps
// 2、connectHOC(selectorFactory,{
// // initMapStateToProps->initProxySelector->proxy->mapStateToProps 获得传入的props
// initMapStateToProps,
// initMapDispatchToProps,
// initMergeProps,
// ...
// })
// 3、connectAdvanced(selectorFactory,{...})
// 4、wrapWithConnect(WrappedComponent)
// new Connect()
// this.selector.run(this.props)
// 调用run(this.props)
// ->sourceSelector(store.getState(), props)
// ->mergedProps = mergeProps(stateProps, dispatchProps, ownProps)
// 传递属性给要封装的组件
// 5、hoistStatics(Connect,WrappedComponent)