前面寫了兩篇文章《React組件性能優(yōu)化》《Redux性能優(yōu)化》餐抢,分別針對(duì)React和Redux在使用上的性能優(yōu)化給了一些建議。但是React和Redux一起使用還需要一個(gè)工具React-Redux碳锈,這一篇就說(shuō)一下React-Redux在使用上的一些性能優(yōu)化建議欺抗。
React-Redux是官方的React和Redux鏈接工具
Provider
一個(gè)很簡(jiǎn)單的React組件,它主要的作用是把store放到context中贸人,connect就可以獲取store,使用store的方法艺智,比如dispatch。其實(shí)沒(méi)有被connect的組件通過(guò)聲明contextTypes屬性也是可以獲取store封拧,使用store的方法的夭问,但是這個(gè)時(shí)候,如果使用dispatch修改了store的state甲喝,React-Redux并不能把修改后的state作為props給React組件铛只,可能會(huì)導(dǎo)致UI和數(shù)據(jù)不同步,所以這個(gè)時(shí)候一定要清楚自己在做什么直撤。
connect
一個(gè)柯里化函數(shù)蜕着,函數(shù)將被調(diào)用兩次。第一次是設(shè)置參數(shù)蓖乘,第二次是組件與 Redux store 連接韧骗。connect 函數(shù)不會(huì)修改傳入的 React 組件,返回的是一個(gè)新的已與 Redux store 連接的組件袍暴,而且你應(yīng)該使用這個(gè)新組件。connect的使用方式是connect([mapStateToProps], [mapDispatchToProps], [mergeProps], [options])(Component)
岗宣,第一次調(diào)用的時(shí)候4個(gè)參數(shù)都是可選淋样。
- mapStateToProps在store發(fā)生改變的時(shí)候才會(huì)調(diào)用耗式,然后把返回的結(jié)果作為組件的props。
- mapDispatchToProps主要作用是弱化Redux在React組件中存在感,讓在組件內(nèi)部改變store的操作感覺(jué)就像是調(diào)用一個(gè)通過(guò)props傳遞進(jìn)來(lái)的函數(shù)一樣刊咳。一般會(huì)配合Redux的bindActionCreators使用措嵌。如果不指定這個(gè)函數(shù),dispatch會(huì)注入到你的組件props中芦缰。
- mergeProps用來(lái)指定mapStateToProps企巢、mapDispatchToProps、ownProps(組件自身屬性)的合并規(guī)則让蕾,合并的結(jié)果作為組件的props浪规。如果要指定這個(gè)函數(shù),建議不要太復(fù)雜探孝。
- options里面主要關(guān)注pure笋婿,如果你的組件僅依賴props和Redux的state顿颅,pure一定要為true缸濒,這樣能夠避免不必要的更新。
- Component就是要被連接的React組件粱腻,組件可以是任意的庇配,不一定是AppRoot。一般會(huì)是需要更新store绍些、或者是依賴store中state的最小組件捞慌。因?yàn)楸贿B接的組件在Redux的state改變后會(huì)更新,大范圍的更新對(duì)性能不友好柬批,而且其中有些組件可能是沒(méi)必要更新也會(huì)更新啸澡,所以要盡量拆分、細(xì)化氮帐,connect僅僅要更新store或依賴store的state的最小組件嗅虏。
Reselect
mapStateToProps也被叫做selector,在store發(fā)生變化的時(shí)候就會(huì)被調(diào)用上沐,而不管是不是selector關(guān)心的數(shù)據(jù)發(fā)生改變它都會(huì)被調(diào)用皮服,所以如果selector計(jì)算量非常大,每次更新都重新計(jì)算可能會(huì)帶來(lái)性能問(wèn)題奄容。Reselect能幫你省去這些沒(méi)必要的重新計(jì)算冰更。
Reselect 提供 createSelector 函數(shù)來(lái)創(chuàng)建可記憶的 selector。createSelector 接收一個(gè) input-selectors 數(shù)組和一個(gè)轉(zhuǎn)換函數(shù)作為參數(shù)昂勒。如果 state tree 的改變會(huì)引起 input-selector 值變化蜀细,那么 selector 會(huì)調(diào)用轉(zhuǎn)換函數(shù),傳入 input-selectors 作為參數(shù)戈盈,并返回結(jié)果奠衔。如果 input-selectors 的值和前一次的一樣谆刨,它將會(huì)直接返回前一次計(jì)算的數(shù)據(jù),而不會(huì)再調(diào)用一次轉(zhuǎn)換函數(shù)归斤。這樣就可以避免不必要的計(jì)算痊夭,為性能帶來(lái)提升。
總結(jié)
謹(jǐn)慎使用context中的store
被connect組件更新的時(shí)候影響范圍盡量小脏里,避免不必要更新
使用Resselect避免不必要的selector計(jì)算