React源码系列-connect源码分析

connect源码分析

  • connect使用方式
import React, { Component } from 'react'
import { connect } from './react-redux'

class App extends Component {
  render () {
    return (
      <div>
        <p >{ this.props.age }}</p>
      </div>
    )
  }
}
const mapStateToProps = (state) => {
  return {
    age: state.age
  }
}
export default connect(mapStateToProps)(App)


从使用方式可以看出,connect的作用就是将redux里面的store相应的参数赋值到connect包裹的组件的props上

  • connect,实现方式
export const connect = (mapStateToProps) => (WrappedComponent) => {
  class Connect extends Component {
    // 获取到Provider提供的context必须要有
    static contextTypes = {
      store: PropTypes.object
    }

    constructor () {
      super()
      this.state = { allProps: {} }
    }

    componentWillMount () {
      const { store } = this.context // 由于Provider设置了Context,这里可以访问到全局的context
      this._updateProps() // 初始化
      store.subscribe(() => this._updateProps()) // 当store的属性发生改变时,更新connect包裹的组件的属性值
    }

    _updateProps () {
      const { store } = this.context
      // 将mapStateToProps的所有属性传给connect包裹的组件
      let stateProps = mapStateToProps(store.getState(), this.props) 
      this.setState({
        allProps: { // 整合普通的 props 和从 state 生成的 props
          ...stateProps,
          ...this.props
        }
      })
    }

    render () {
      return <WrappedComponent {...this.state.allProps} />
    }
  }
  return Connect
}


connect 本质是一个函数柯里化的高阶组件,将mapStateToProps返回的对象作为其被包裹的组件的属性

  • store.subscribe帮助connect监听数据变化,实现组件重新渲染
function createStore (reducer, state) {
  const listeners = []
  const getState = () => state

 // subscribe接受一个监听函数,并将其放入监听队列中
  const subscribe = (listener) => listeners.push(listener)

  // 最关键的部分,每次dispatch的时候都会遍历监听队列,然后调用监听函数
  const dispatch = (action) => {
    reducer(state, action)
    listeners.forEach((listener) => listener())
  }
  return { getState, dispatch, subscribe }
}


所以上面connect包裹的组件能够在store的数据发生改变的时候重新更新被包裹的组件


// 将_updateProps放入监听队列中
store.subscribe(() => this._updateProps())

// 每次dispatch的时候都会遍历监听队列,并且调用监听者_updateProps()实现connect被包裹的组件的更新
const dispatch = (action) => {
    stateChanger(state, action)
    listeners.forEach((listener) => listener())
}


参考文章:http://huziketang.mangojuice.top/books/react/lesson31

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值