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;