import Counter from '../components/Counter';
import { increment, decrement, incrementIfOdd, incrementAsync } from '../actions';
import { bindActionCreators } from 'redux';
import React, { Component, createElement } from 'react';
import PropTypes from 'prop-types';
import hoistStatics from 'hoist-non-react-statics'
import * as ActionCreators from '../actions';
const storeShape = PropTypes.shape({
subscribe: PropTypes.func.isRequired,
dispatch: PropTypes.func.isRequired,
getState: PropTypes.func.isRequired
});
const connect = function(mapStateToProps, mapDispatchToProps){
return function(WrappedComponent){
class Connect extends Component {
constructor(props, context) {
super(props, context)
this.store = props.store || context.store;
const storeState = this.store.getState()
this.state = { storeState }
}
handleChange() {
const storeState = this.store.getState();
this.setState({ storeState });
}
trySubscribe() {
this.store.subscribe(this.handleChange.bind(this))
this.handleChange();
}
componentDidMount() {
this.trySubscribe();
}
render() {
let store = this.store;
let dispatch = store.dispatch;
let mergedProps = {};
let dispatchProps;
// 若它是个函数
if (typeof mapDispatchToProps == 'function'){
dispatchProps = mapDispatchToProps;
} else if(!mapDispatchToProps){
// 若没有传递参数
dispatchProps = dispatch => ({ dispatch });
} else {
// 若 mapDispatchToProps 是一个对象
const wrapActionCreators = function(actionCreators) {
return function (dispatch) {
return bindActionCreators(actionCreators, dispatch);
};
}
dispatchProps = wrapActionCreators(mapDispatchToProps);
// 若它是个对象, 属性值 是一个action create, 类似
// for(let j in mapDispatchToProps){
// dispatchProps[j] = () => {
// dispatch(mapDispatchToProps[j]());
// }
// }
}
dispatchProps = dispatchProps(dispatch);
let stateProps = mapStateToProps( this.state.storeState );
for(let i in stateProps){
mergedProps[i] = stateProps[i];
}
for(let i in dispatchProps){
mergedProps[i] = dispatchProps[i];
}
return createElement(WrappedComponent,
mergedProps
);
}
}
Connect.contextTypes = {
store: storeShape
}
Connect.propTypes = {
store: storeShape
}
return hoistStatics(Connect, WrappedComponent);
}
}
export default connect(
state => ({ counter: state.counter }),
/*
注意这里写成如下形式不会被执行
dispatch => ({
increment: increment,
decrement: decrement,
incrementIfOdd: incrementIfOdd,
incrementAsync: incrementAsync,
})
*/
// dispatch => ({
// increment: () => dispatch( increment() ),
// decrement: () => dispatch( decrement() ),
// incrementIfOdd: () => dispatch( incrementIfOdd() ),
// incrementAsync: () => dispatch( incrementAsync() )
// })
// ActionCreators
dispatch => bindActionCreators(ActionCreators, dispatch)
)(Counter);