自己实现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;

猜你喜欢

转载自blog.csdn.net/weixin_43564237/article/details/84405245