connect函数在之前的bindActionCreator中提到了一些,它的主要作用便是接收参数,包装组件,返回一个新的容器组件
connect([mapStateToProps], [mapDispatchToProps], [mergeProps], [options])(Component)
通过connect包装后,作为参数传入的组件便拥有了由mapStateToProps、mapDispatchToProps传入的props。实际上,主要逻辑也不是很复杂,下面看一下简化版代码
/* connect.js */
import React from 'react';
import PropTypes from 'prop-types';
import { bindActionCreators } from '../mini-redux';
// connect是一个高阶函数
export const connect = (mapStateToProps = state => state, mapDispatchToProps = {}) => Component => {
return class WrappedComponent extends React.Component {
// 必须声明contextTypes类型,否则无法访问this.context
static contextTypes = {
store: PropTypes.object
};
state = {
props: {}
};
componentDidMount() {
// 第一次组件挂载时会初始化执行一次
this.mapToProps();
// 订阅更新,后续每当store.dispatch执行时都调用该监听函数
this.context.store.subscribe(() => this.mapToProps());
}
mapToProps() {
// 组件本身传入的props
const ownProps = this.props;
// 执行mapStateToProps函数
const stateToProps = mapStateToProps(
this.context.store.getState(),
ownProps
);
// 将传入的mapDispatchToProps传入bindActionCreators进行处理
const dispatchToProps = bindActionCreators(
mapDispatchToProps,
this.context.store.dispatch,
ownProps
);
// 更新props
this.setState({
props: { ...this.state.props, ...stateToProps, ...dispatchToProps }
});
}
// 如何实现类似PureComponent
shouldComponentUpdate(nextProps, nextState) {
// 添加shallow compare
const nextPropsKeys = Object.keys(nextProps);
const nextStateKeys = Object.keys(nextState);
// 只要有一个数据发生变化便会更新组件
return (
nextPropsKeys.some(key => nextProps[key] !== this.props[key]) ||
nextStateKeys.some(key => nextState[key] !== this.state[key])
);
}
render() {
return <Component {...this.state.props} />;
}
};
};
相关文章
mini-redux系列之一:createStore
mini-redux系列之二:applyMiddleware
mini-redux系列之三:combineReducers
mini-redux系列之四:bindActionCreators
mini-react-redux系列之一:Provider
mini-react-redux系列之二:connect
redux-thunk以及自定义redux中间件
网友评论