返回

React-Redux 7 源码解析——connect

前端

前言

在上一篇文章中,我们分析了 Provider 的源码,以及用 Context 全局状态管理的问题。本文我们将进入 connect 的源码,看看 react-redux 是如何解决这些问题的。

connect 函数的实现

connect 函数是 react-redux 提供的一个高阶组件(HOC),它接受一个 React 组件作为参数,返回一个新的 React 组件,这个新的组件连接了 Redux store 和原组件,使原组件能够访问 Redux store 中的状态和 dispatch 方法。

connect 函数的实现比较复杂,但其核心思想很简单:

  1. 它首先创建一个新的组件类,这个新的组件类继承自原组件类。
  2. 然后,它在新的组件类的构造函数中,将 Redux store 作为参数传递给原组件类。
  3. 最后,它返回新的组件类。

这样,原组件类就可以通过 this.props.store 访问 Redux store,并通过 this.props.dispatch 派发 action。

connect 函数的使用

connect 函数的使用也非常简单,只需要在需要连接 Redux store 的组件中,使用 connect 函数包裹组件即可。例如:

import React, { Component } from 'react';
import { connect } from 'react-redux';

class MyComponent extends Component {
  render() {
    return (
      <div>
        <h1>{this.props.count}</h1>
        <button onClick={this.props.incrementCount}>Increment</button>
      </div>
    );
  }
}

const mapStateToProps = (state) => {
  return {
    count: state.count
  };
};

const mapDispatchToProps = (dispatch) => {
  return {
    incrementCount: () => dispatch({ type: 'INCREMENT_COUNT' })
  };
};

export default connect(mapStateToProps, mapDispatchToProps)(MyComponent);

在上面的代码中,我们使用 connect 函数包裹了 MyComponent 组件,并指定了 mapStateToProps 和 mapDispatchToProps 两个函数。mapStateToProps 函数将 Redux store 中的状态映射到组件的 props,而 mapDispatchToProps 函数将 Redux store 的 dispatch 方法映射到组件的 props。这样,MyComponent 组件就可以通过 this.props.count 访问 Redux store 中的 count 状态,并通过 this.props.incrementCount 派发 INCREMENT_COUNT action。

connect 函数的源码分析

connect 函数的源码比较复杂,这里我们只分析其中几个关键部分。

首先,connect 函数首先创建一个新的组件类,这个新的组件类继承自原组件类。这个新的组件类被称为 connect 组件类。

function connect(mapStateToProps, mapDispatchToProps, mergeProps, options) {
  return (WrappedComponent) => {
    class Connect extends Component {
      constructor(props) {
        super(props);
        connectClass.prototype.wrappedComponentRef = React.createRef();
        connectClass.prototype.handleWrappedComponentRef = (inst) => {
          connectClass.prototype.wrappedComponentRef.current = inst;
        };
      }
      ...

然后,connect 函数在 connect 组件类的构造函数中,将 Redux store 作为参数传递给原组件类。

constructor(props) {
  super(props);
  connectClass.prototype.wrappedComponentRef = React.createRef();
  connectClass.prototype.handleWrappedComponentRef = (inst) => {
    connectClass.prototype.wrappedComponentRef.current = inst;
  };
  // ...
  const { store } = props;
  store.dispatch({ type: '@@INIT' });
  const contextValue = { store };
  updateStateWhenMounted.bind(this)(contextValue);
}

最后,connect 函数返回 connect 组件类。

      ...
      return React.createElement(WrappedComponent, assign(
        {},
        props,
        getDerivedStateFromProps(props, mergedState),
        getListeners(props, dispatch, mergedState),
        proxyWrappedMethods(wrappedMethods, ref),
      ));
    };
    ...

总结

connect 函数是 react-redux 提供的一个高阶组件,它可以将 React 组件连接到 Redux store,使组件能够访问 Redux store 中的状态和 dispatch 方法。connect 函数的使用非常简单,只需要在需要连接 Redux store 的组件中,使用 connect 函数包裹组件即可。connect 函数的源码比较复杂,但其核心思想很简单:它首先创建一个新的组件类,这个新的组件类继承自原组件类;然后,它在新的组件类的构造函数中,将 Redux store 作为参数传递给原组件类;最后,它返回新的组件类。这样,原组件类就可以通过 this.props.store 访问 Redux store,并通过 this.props.dispatch 派发 action。