function createState(reducer) {
let state = null;
const listeners = [];
// 这个函数是 redux 的函数,用来收集 改变的 内容
// 类比的话,就是 vue 的 dep
const subscribe = (listener) => listeners.push(listener);
const getState = () => state;
const dispatch = (action) => {
state = reducer(state, action);
// 可以看到,当执行 dispatch 的时候,将所有的 改变内容都执行一边
listeners.forEach((listener) => listener());
}
dispatch({});
// 然后将 我们要用到的 getState, dispatch, subscribe 给暴露出去
return { getState, dispatch, subscribe }
}
// 这里是使用了 react 的 上下文内容,不赘述;
export class Provide extends Component {
static propTypes = {
store: PropTypes.object,
children: PropTypes.any
}
static childContextTypes = {
store: PropTypes.object
}
getChildContext() {
return {
store: this.props.store
}
}
render() {
return (
<div>{this.props.children}</div>
)
}
}
// 在这里可以看到
// connect()(component) 这个函数的执行过程
// 首先返回一个 函数,那个函数也是高阶函数 ,然后 用这个返回的 高阶函数 将 子组件给包起来
export const connect = (mapStateToProps, mapDispatchToProps) => (WrappedCompent) => {
// 这个 组件 就是真正将 自己使用组件包起来的
class Connect extends Component{
static contextTypes = {
store: PropTypes.object
}
constructor() {
super()
this.state = { allProps: {} }
}
componentWillMount = () => {
const { store } = this.context;
this._updateProps();
// 正如上文所说,这里 就是 调用了 subscribe,当数据改变了之后,
// 将改变的事件分发 到这里,然后 执行 this._updateProps()
// 这样就做到了 响应
store.subscribe(() => this._updateProps());
}
_updateProps() {
// 再来看这里
const { store } = this.context
let stateProps = mapStateToProps
? mapStateToProps(store.getState(), this.props)
: {} // 防止 mapStateToProps 没有传入
let dispatchProps = mapDispatchToProps
? mapDispatchToProps(store.dispatch, this.props)
: {} // 防止 mapDispatchToProps 没有传入
// 这里实际上 就是 将 所有的 需要获得的 state 给传进来
this.setState({
allProps: {
...stateProps,
...dispatchProps,
...this.props
}
})
}
render() {
// const { store } = this.context;
// let stateProps = mapStateToProps(store.getState());
// 然后将所有的 数据都传到这里
// 在这种情况下,props 也就是 redux 的store 里的数据改变了,就会
// 触发 数据的 重新渲染
return <WrappedCompent {...this.state.allProps} />
}
}
return Connect;
}
- 首先 将数据收集起来,这是正常的 state
- 使用 connect 的过程中,将 所有的数据都 通过高阶组件的方式 注入到 子组件中
- 在 connect 的过程中,会使用 redux 的事件派发机制,使用 subscribe 将 高阶组件的 store 给绑定住
- 所以 当 dispatch 改变数据的时候,会触发 subscribe ,从而 触发 高阶组件 store 的改变
- 这样 store 改变了,就会 使子组件,也就是使用 数据的组件的 props 改变
- 这样监听到 props 改变了,就会触发 渲染