React-Redux核心
React-Redux核心API:
Redux 官方提供的 React 绑定库。具有高效且灵活的特性。
- Provider 组件
用于在应用顶层提供store。 - connect 函数
用于给组件提供store的状态和dispatch方法。接收四个参数,返回一个高阶组件。
逐步代码实现(涉及ES6和JSX语法):
Provider
1、首先Provider是一个顶层容器组件,接收一个store参数:
import React from 'react';
import PropTypes from 'prop-types';
export default class Provider extends React.Component {
static propTypes = {
store: PropTypes.object.isRequired
}
render(){
return this.props.children;
}
}
2、将store挂载到context上,以便让子组件访问到:
import React from 'react';
import PropTypes from 'prop-types';
export default class Provider extends React.Component {
static propTypes = {
store: PropTypes.object.isRequired
}
/* 新增代码 */
getChildrenContext(){
return { store: this.props.store};
}
* *********** */
render(){
return this.props.children;
}
}
可以看到,Provider的实现非常简单。
connect
connect的实现比较复杂,它应接收四个参数:
mapStateToProps
回调函数,接收当前的state作为参数,返回一个对象作为组件的参数;mapDispatchToProps
回调函数,接收store的dispatch方法作为参数,返回值同上;mergeProps
回调函数,接收前两个函数的返回值以及组件本身的参数作为参数,返回值作为传递给组件的最终的参数。options
配置项,暂且不管。
1、connect大概的样子:
它接收三个参数,返回一个高阶组件。
import React from 'react';
import PropTypes from 'prop-types';
const connect = (
mapStateToProps,
mapDispatchToProps,
mergeProps
) => {
const withConnect = Comp =>
class CompWithConnect extends React.Component{
render(){
const finalProps = this.props;
return <Comp { ...finalProps } />
}
};
return withConnect;
};
export default connect;
2、先让组件获取store,并获取所需的state及dispatch方法:
import React from 'react';
import PropTypes from 'prop-types';
const connect = (
mapStateToProps,
mapDispatchToProps,
mergeProps
) => {
const withConnect = Comp =>
class CompWithConnect extends React.Component{
/* 新增代码 */
static contextTypes = {
store: PropTypes.object
}
/* ********** */
render(){
/* 新增代码 */
const currentState = this.context.store.getState();
const dispatch = this.context.store.diaptch;
/* ********** */
const finalProps = this.props;
return <Comp { ...finalProps } />
}
};
return withConnect;
};
export default connect;
3、考虑到参数是可选的,应提供三个方法的默认值:
import React from 'react';
import PropTypes from 'prop-types';
/* 新增代码 */
const defaultMapStateToProps = () => ({});
const defaultMapDispatchToProps = () => ({});
const defaultMergeProps = (
mappedStateProps,
mappedDipatchProps,
ownProps
) => ({
...ownProps,
...mappedStateProps,
...mappedDipatchProps
});
/* ********** */
const connect = (
mapStateToProps,
mapDispatchToProps,
mergeProps
) => {
/* 新增代码 */
const finalMapStateToProps = mapStateToProps||defaultMapStateToProps;
const finalMapDispatchToProps = mapDispatchToProps||defaultMapDispatchToProps;
const finalMergeProps = mergeProps||defaultMergeProps;
/* ********** */
const withConnect = Comp =>
class CompWithConnect extends React.Component{
static contextTypes = {
store: PropTypes.object
}
render(){
const currentState = this.context.store.getState();
const dispatch = this.context.store.diaptch;
const finalProps = this.props;
return <Comp { ...finalProps } />
}
};
return withConnect;
};
export default connect;
4、计算子组件的参数:
import React from 'react';
import PropTypes from 'prop-types';
const defaultMapStateToProps = () => ({});
const defaultMapDispatchToProps = () => ({});
const defaultMergeProps = (
mappedStateProps,
mappedDipatchProps,
ownProps
) => ({
...ownProps,
...mappedStateProps,
...mappedDipatchProps
});
const connect = (
mapStateToProps,
mapDispatchToProps,
mergeProps
) => {
const finalMapStateToProps = mapStateToProps||defaultMapStateToProps;
const finalMapDispatchToProps = mapDispatchToProps||defaultMapDispatchToProps;
const finalMergeProps = mergeProps||defaultMergeProps;
/* 新增代码 */
const computedProps = (currentState, dispatch, ownProps) => finalMergeProps(finalMapStateToProps(currentState), finalMapDispatchToProps(dispatch), ownProps);
/* ********** */
const withConnect = Comp =>
class CompWithConnect extends React.Component{
static contextTypes = {
store: PropTypes.object
}
render(){
const currentState = this.context.store.getState();
const dispatch = this.context.store.diaptch;
/* 修改代码 */
const finalProps = computedProps(currentState, dispatch, this.props);
/* ********** */
return <Comp { ...finalProps } />
}
};
return withConnect;
};
export default connect;