export const connect = (mapStateToProps, mapDispatchToProps) => 
  (WrappedComponent) => {
    class Connect extends Component {
       static contextTypes = {
         store: PropTypes.object
       }
       constructor () {
         super()
         this.state = {
           allProps: {}
         }
       }
       componentWillMount () {
        // 获取context store ,来源provider 组件
         const { store } = this.context 
         this._updateProps()
         // store 里加入这个updatedProps 订阅
         store.subscribe(() => this._updateProps()) 
         //为什么不直接用this._updateProps, 而是用箭头函数,为了 _updateProps 保存this指向 本组件this
       }
       _updateProps () {
         const { store } = this.context
         let stateProps = mapStateToProps
           ? mapStateToProps(store.getState(), this.props)
           : {} // 防止 mapStateToProps 没有传入
         let dispatchProps = mapDispatchToProps
           ? mapDispatchToProps(store.dispatch, this.props)
           : {} // 防止 mapDispatchToProps 没有传入
         this.setState({
            allProps: {
             ...stateProps,
             ...dispatchProps,
             ...this.props
            }
         })
       }
       render () {
         return
       } 
     }
  return Connect
}
export class Provider extends Component {
    static propTypes = {
       store: PropTypes.object,
       children: PropTypes.any
    }
    static childContextTypes = {
       store: PropTypes.object
     }
     getChildContext () {
       return {
         store: this.props.store // 向context 写store
       }
     }
     render () {
        return (
           {this.props.children}
         )
     }
}
function createStore (reducer) {
    let state = null
    const listeners = [ ];
    const subscribe = (listener) => listeners.push(listener)
    const getState = () => state
    const dispatch = (action) => {
      state = reducer(state, action);
      listeners.forEach((listener) => listener())
    }
    // 每一次dispatch 都会更新所有订阅
    dispatch({}) // 初始化 state
    return { getState, dispatch, subscribe }
}
// App.js:
const themeReducer = (state, action) => {
   if (!state) return {
    themeColor: 'red'
   }
   switch (action.type) {
     case 'CHANGE_COLOR':
       return { ...state, themeColor: action.themeColor }
     default:
       return state
    }
 }
const store = createStore(themeReducer)
class App extends Component {
    render() {
       return (
      );
    }
}
export default App;