实现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
}
}