Redux—connect的原理及实现

实现connect高阶函数

我们在使用react-redux的时候都会使用connect,connect使用起来相对来说是很方便的。接下来我们从connect的原理来学习,然后试着重新封装一个connect函数。

(代码也不多,就直接贴代码了)

import { Component } from 'react'
import store from '../store/index'

/**
 * @author topu
 * @date 2023/5/29
 * @Description connect是一个函数,参数需要我们传入两个函数,然后返回值是一个高阶函数,需传入一个组件
 * @return function(*): NewComponent
 * @param mapStateToProps
 * @param mapDispatchToProps
 */
export function connect (mapStateToProps, mapDispatchToProps) {
  return function (WrapperComponent) {
    class NewComponent extends Component {
      // 当数据改变的时候需要进行刷新
      componentDidMount () {
        store.subscribe(() => {
          this.forceUpdate()
        })
      }
      
      // 调用connect组件的时候,需要我们将需要使用的store里面的数据挂载到组件的props中
      render () {
        // mapStateToProps的调用:
        // const mapStateProps = (state) => {
        //   return {
        //     counter: state.counter.counter
        //   }
        // }
        // 这里的state的结果就是我们调用mapStateToProps传入的obj
        // 获取需要传入的需要挂载的数据和函数
        const stateObj = mapStateToProps(store.getState())
        const dispatchObj = mapDispatchToProps(store.dispatch)
        // 将数据,函数挂载到组件的props中
        return <WrapperComponent {...stateObj} {...dispatchObj}/>
      }
    }
    
    return NewComponent
  }
}

这样就可以初步实现connect函数了

但是这样写的话store的任何数据修改都会引起组件重新加载,如何实现只有我们使用的数据改变了,页面才重新加载?还可以进行以下优化。

import { pureComponent } from 'react'
import store from '../store/index'

/**
 * @author topu
 * @date 2023/5/29
 * @Description connect是一个函数,参数需要我们传入两个函数,然后返回值是一个高阶函数,需传入一个组件
 * @return function(*): NewComponent
 * @param mapStateToProps
 * @param mapDispatchToProps
 */
export function connect (mapStateToProps, mapDispatchToProps) {
  return function (WrapperComponent) {
    class NewComponent extends pureComponent {
      constructor (props) {
        super(props)
        this.state = mapStateToProps(store.getState())
      }
      
      // 当数据改变的时候需要进行刷新
      componentDidMount () {
        store.subscribe(() => {
          // 每次store的数据发生改变,会就调用setState,然后pureComponent底层就会帮助我们进行对比,看是否页面的数据发生了改变,判断是否进行刷新
          this.setState = mapStateToProps(store.getState())
        })
      }
      
      // 调用connect组件的时候,需要我们将需要使用的store里面的数据挂载到组件的props中
      render () {
        // mapStateToProps的调用:
        // const mapStateProps = (state) => {
        //   return {
        //     counter: state.counter.counter
        //   }
        // }
        // 这里的state的结果就是我们调用mapStateToProps传入的obj
        // 获取需要传入的需要挂载的数据和函数
        const stateObj = mapStateToProps(store.getState())
        const dispatchObj = mapDispatchToProps(store.dispatch)
        // 将数据,函数挂载到组件的props中
        return <WrapperComponent {...stateObj} {...dispatchObj}/>
      }
    }
    
    return NewComponent
  }
}

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值