# 迷你版redux实现

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

	const getState = ()=>currentState
	const subscribe = (listener)=>{
		currentListeners.push(listener)
	}
	const dispatch = action=>{
		currentState = reducer(currentState, action)
		currentListeners.forEach(v=>v())
		return action
	}
	dispatch({type:'@@INIT'})
	return {getState,subscribe,dispatch}
}

//中间件实现
export applyMiddleWare(...middlewares){
	return createStore=>...args=>{
		const store = createStore(...args)
		let dispatch = store.dispatch

		const midApi = {
			getState:store.getState,
			dispatch:...args=>dispatch(...args)
		}
		const middlewaresChain = middlewares.map(middleware=>middleware(midApi))
		dispatch = compose(...middlewaresChain)(store.dispatch)
		return {
			...store,
			dispatch
		}
	}

// fn1(fn2(fn3())) 把函数嵌套依次调用
export function compose(...funcs){
	if(funcs.length===0){
		return arg=>arg
	}
	if(funs.length===1){
		return funs[0]
	}
	return funcs.reduce((ret,item)=>(...args)=>ret(item(...args)))
}


//bindActionCreator实现

function bindActionCreator(creator,dispatch){
    return ...args=>dispatch(creator(...args))
}
function bindActionCreators(creators,didpatch){
    //let bound = {}
    //Object.keys(creators).forEach(v=>{
   //     let creator = creator[v]
     //   bound[v] = bindActionCreator(creator,dispatch)
    //})
    //return bound
    
    return Object.keys(creators).reduce((ret,item)=>{
	    ret[item] = bindActionCreator(creators[item],dispatch)
    	return ret
    },{})
}

# react-redux实现

例子 provider组件就是使用context,把store放到context里,所有的子元素可以直接取到store

import PropTypes from 'prop-types'
class Provider extends Component {
    static childContextTypes = {
        store:Protypes.object
    }
    constructor(props,context){
        super(props,context)
        this.store = props.store
    }
    getChildContext(){
        //把传进来的store放进全局
        return {store:this.store}
    }
    render(){
        return this.props.children
    }
}

connect 负责连接组件,给到redux里的数据放到组件的属性里

  • 负责接收一个组件,把state里的一些数据放进去,返回一个组件
  • 数据变化的时候,能够通知组件
//高阶组件写法
const connect = (mapStateToProps=state=>state,mapDispatchToProps={})=>(wrapperComponent)=>{
    return class ConnectComponent extends React.Component {
        //负责接收组件
        static contextTypes = {
            store:PropTypes.obejct
        }
        constructor(props){
            super(props, context){
                this.state = {
                    props:{}
                }
            }
        }
        componentDidMount(){
            const {store} = this.context
            store.subscribe(()=>this.update())
            this.update()
        }
        update(){
            //  获取mapStateToProps、mapDispatchToProps 放入this.props里
            
            const {store}=this.context
            const stateProps = mapStateToProps(store.getState())
            const dispatchProps = bindActionCreators(mapDispatchProps,store.dispatch)
            this.setState({
                props:{
                    ...this.state.props,
                    ...stateProps,
                    ...dispatchProps
                 }
            })
        }
        render(){
            // 把数据放入
            return <wrapperComponent {...this.state.props}/>
        }
    }
}

自己造一个中间件

const thunk = ({dispatch,getState})=>next=>action=>{

	if(typeof action == 'function'){
		return action(dispatch,getState)
	}
	if(Array.isArray(action){
		return action.forEach(v=>dispatch(v))
	}
	//默认 什么都不做
	return next(action)
}
阅读全文