由于本期采用的小程序框架是taro 偶然看到以下寫法
@connect(({ counter }) => ({
counter
}), (dispatch) => ({
add() {
dispatch(add())
}
}))
class Index extends Component {}
看了typescript才發(fā)現(xiàn)是裝飾器 官方文檔如下
https://www.tslang.cn/docs/handbook/decorators.html#class-decorators
裝飾器在js中還在建議搜集階段,所以很少人使用,bable 安裝插件也是可以支持的,目前babel編譯器已經(jīng)支持裝飾器了,裝飾器分為5種:類裝飾器 方法裝飾器 訪問器裝飾器 屬性裝飾器 參數(shù)裝飾器
裝飾器,顧名思義就是在裝飾類,看前面的代碼,這個(gè)connect的作用就是為了后面的 class index 這個(gè)類添加一些內(nèi)部屬性和方法,方便組件內(nèi)部引用 添加的這些屬性和方法都是通過傳參過去的 所以組件的壓力沒那么大 都是一些必須要的屬性和方法
這里我們只解析類裝飾器,在taro當(dāng)中tarojs > redux > src里面可以找到connect的源碼大概就是下面這些:為了學(xué)習(xí), 逐行理解
import { getStore } from '../utils/store' // 從store引入了一個(gè)taro獲得store的方法
import { mergeObjects, isObject } from '../utils' // 引入兩個(gè)方法 深拷貝 和 判斷是否為對象
export default function connect (mapStateToProps, mapDispatchToProps) { // 參數(shù)為兩個(gè)方法
const store = getStore() // 獲取當(dāng)前的store
const dispatch = store.dispatch // 變量dispatch
const initMapDispatch = typeof mapDispatchToProps === 'function' ? mapDispatchToProps(dispatch) : {} // 判斷傳入的mapDispatchToProps是否為方法來初始化組件的內(nèi)部方法對象
initMapDispatch.dispatch = dispatch
const stateListener = function () {
let isChanged = false
const newMapState = mapStateToProps(store.getState())
Object.keys(newMapState).forEach(key => {
let val = newMapState[key]
if (isObject(val) && isObject(initMapDispatch[key])) {
val = mergeObjects(val, initMapDispatch[key])
}
this.prevProps = Object.assign({}, this.props)
if (this.props[key] !== val) {
this.props[key] = val
isChanged = true
}
})// 這一整個(gè)方法是根據(jù)傳入的參數(shù)初始化state對象, 并且判斷initMapDispatch是否有同名屬性 ,如果有, 進(jìn)行mergeObjects合并
const isPageHide = this.$root ? this.$root.$isPageHide : this.$isPageHide
if (isChanged && !isPageHide) {
this._unsafeCallUpdate = true
this.setState({}, () => {
delete this._unsafeCallUpdate
})
}
} // 這個(gè)略過
// 從這里開始才是在編譯時(shí)執(zhí)行的方法
return function connectComponent (Component) { // 這里的Component參數(shù) 就是后面的類
let unSubscribe = null
return class Connect extends Component { // 返回一個(gè)派生類
constructor () { // 重寫index類的constructor 并為它寫入傳入的state和方法
super(Object.assign(...arguments, mergeObjects(mapStateToProps(store.getState()), initMapDispatch)))
Object.keys(initMapDispatch).forEach(key => {
this[`__event_${key}`] = initMapDispatch[key]
})
}
componentWillMount () { // 重寫componentWillMount
const store = getStore()
Object.assign(this.props, mergeObjects(mapStateToProps(store.getState()), initMapDispatch))
unSubscribe = store.subscribe(stateListener.bind(this))
if (super.componentWillMount) {
super.componentWillMount()
}
}
// ... 同理以下都是重寫方法
componentDidShow () {}
componentDidHide () {}
componentWillUnmount () { }
}
}
}