摘要:通過可以讓識別列表長度變化自動更新列表,利用維護(hù)項數(shù)據(jù)可以使每個項保持響應(yīng)式卻互不影響,對長列表優(yōu)化效果很明顯。最好的方式是將數(shù)據(jù)統(tǒng)一放在中,子組件通過方式獲取數(shù)據(jù)。
MobX 是一款十分優(yōu)秀的狀態(tài)管理庫,不但書寫簡潔還非常高效。當(dāng)然這是我在使用之后才體會到的,當(dāng)初試水上車的主要原因是響應(yīng)式,考慮到可能會更符合 Vue 過來的思考方式。然而其實(shí)兩者除了響應(yīng)式以外并沒有什么相似之處。
在使用過程中走了不少彎路,一部分是因為當(dāng)時掃兩眼文檔就動手,對 MobX 機(jī)制理解得不夠;其它原因是 MobX 終究只是一個庫,會受限于 React 機(jī)制,以及與其它非 MobX 管理組件的兼容問題。當(dāng)中很多情況在文檔已經(jīng)給出了說明(這里和這里),我根據(jù)自己遇到的再做一番總結(jié)。
與非響應(yīng)式組件兼容問題與非響應(yīng)式的組件一起工作時,MobX 有時需要為它們提供一份非響應(yīng)式的數(shù)據(jù)副本,以免 observable 被其它組件修改。
observable.ref使用 React Navigation 導(dǎo)航時,如果要交由 MobX 管理,則需要手動配置導(dǎo)航狀態(tài)棧,此時用 @observable.ref “淺觀察”可避免狀態(tài)被 React Navigation 修改時觸發(fā) MobX 警告。
當(dāng) Navigator 接受 navigation props 時代表導(dǎo)航狀態(tài)為手動管理。
import { addNavigationHelpers, StackNavigator } from "react-navigation" import { observable, action } from "mobx" import { Provider, observer } from "mobx-react" import AppComp from "./AppComp" const AppNavigator = StackNavigator({ App: { screen: AppComp }, // ... }, { initialRouteName: "App", headerMode: "none" }) @observer export default class AppNavigation extends Component { @observable.ref navigationState = { index: 0, routes: [ { key: "App", routeName: "App" } ], } @action.bound dispatchNavigation = (action, stackNavState = true) => { const previousNavState = stackNavState ? this.navigationState : null this.navigationState = this.AppNavigator.router.getStateForAction(action, previousNavState) return this.navigationState } render () { return (observable.shallowArray() 與 observable.shallowMap()) } }
MobX 還提供其它方便的數(shù)據(jù)結(jié)構(gòu)來存放非響應(yīng)式數(shù)據(jù)。
比如使用 SectionList 的時候,我們要為其提供數(shù)據(jù)用于生成列表,由于 Native 官方的實(shí)現(xiàn)跟 MobX 不兼容,這個數(shù)據(jù)不能是響應(yīng)式的,不然 MobX 會報一堆警告。
MobX 有個 mobx.toJS() 方法可以導(dǎo)出非響應(yīng)式副本;如果結(jié)構(gòu)不相同還可以使用 @computed 自動生成符合的數(shù)據(jù)。但這兩個方法每次添加項目都要全部遍歷一遍,可能會存在性能問題。
這時其實(shí)可以維護(hù)一個 observable.shallowArray,里面只放 key 數(shù)據(jù),只用于生成列表(像骨架一樣)。傳給 SectionList 的 sections props 時 slice 數(shù)組復(fù)制副本(shallowArray 里的數(shù)據(jù)非響應(yīng)式,所以只需淺復(fù)制,復(fù)雜度遠(yuǎn)小于上面兩種方式)。
然后 store 維護(hù)一個 observable.map 來存放每個項的數(shù)據(jù),在項(item)組件中 inject store 進(jìn)去,再利用 key 從 map 中獲取數(shù)據(jù)來填充。
通過 shallowArray 可以讓 MobX 識別列表長度變化自動更新列表,利用 map 維護(hù)項數(shù)據(jù)可以使每個項保持響應(yīng)式卻互不影響,對長列表優(yōu)化效果很明顯。
// store comp class MyStore { @observable sections = observable.shallowArray() @observable itemData = observable.map() @action.bound appendSection (section) { const data = [] section.items.forEach(action(item => { this.itemData.set(item.id, item) data.push({key: item.id}) })) this.sections.push({ key: section.id, data }) } }
// MyList comp import { SectionList } from "react-native" @inject("myStore") @observer class MyList extends React.Component { _renderItem = ({item}) =>render () { return ( ) } }
// SectionItem comp @inject("myStore") @observer class SectionItem extends React.Component { render () { const {myStore, id} = this.props const itemData = myStore.itemData.get(id) return (computed{itemData.title} ) } }
利用 @computed 緩存數(shù)據(jù)可以做一些優(yōu)化。
比如有一個響應(yīng)式的數(shù)組 arr,一個組件要根據(jù) arr 是否為空更新。如果直接訪問 arr.length,那么只要數(shù)組長度發(fā)生變化,這個組件都要 render 一遍。
此時利用 computed 生成,組件只需要判斷 isArrEmpty 就可以減少不必要的更新:
@computed get isArrEmpty () { return this.arr.length <= 0 }observable.map
因 JS 機(jī)制 MobX 不能檢測屬性的增刪,所以最好用 observable.map 取代簡單 {} 對象。另外 MobX 沒有提供 Set 支持,可以用 key 和 value 一樣的 Map 代替。
避免在父組件中訪問子組件的屬性這條規(guī)則在文檔也提到,原因很簡單,MobX 對于一個 observer 組件,是通過訪問屬性來記錄依賴的。所以哪怕父組件里沒有用到這個屬性,只是為了作為 props 傳給子組件,MobX 還是算它依賴了這個屬性,于是會產(chǎn)生不必要的更新。最好的方式是將數(shù)據(jù)統(tǒng)一放在 store 中,子組件通過 inject store 方式獲取數(shù)據(jù)。
小組件由于 React 的機(jī)制,MobX 只能在組件層面發(fā)光發(fā)熱,對于組件內(nèi)部就無能為力了。所以大組件用 MobX 很容易卡死(用其它也會),小組件才能真正發(fā)揮 MobX 自動管理更新的優(yōu)勢。
博客鏈接:https://blog.crimx.com/2017/1...
【完】
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/89757.html
摘要:的另一個核心特性,蘋果表示也正在開發(fā)中,按開發(fā)進(jìn)度可能幾個月后就能與我們見面。是基于的本地化數(shù)據(jù)庫,支持以及瀏覽器環(huán)境。 前端每周清單專注前端領(lǐng)域內(nèi)容,以對外文資料的搜集為主,幫助開發(fā)者了解一周前端熱點(diǎn);分為新聞熱點(diǎn)、開發(fā)教程、工程實(shí)踐、深度閱讀、開源項目、巔峰人生等欄目。歡迎關(guān)注【前端之巔】微信公眾號(ID: frontshow),及時獲取前端每周清單。 本期是 2017 年的最后一...
摘要:年前公司由一個項目是使用來開發(fā)的所以遇到了一些問題比較影響開發(fā)進(jìn)程的就是路由問題了實(shí)際上就是這個組件比較難懂這里給大家講解一下希望大家少踩點(diǎn)坑另外本篇文章使用的是環(huán)境主要講解的還是如何使用記錄中路由的狀態(tài)但是會穿插一些小內(nèi)容這里雖然講到的是 年前公司由一個項目是使用 ReactNative 來開發(fā)的所以遇到了一些問題,比較影響開發(fā)進(jìn)程的就是路由問題了,實(shí)際上就是 ReactNaviga...
摘要:一其實(shí)是一個比較輕便的可擴(kuò)展的狀態(tài)管理工具,是一個由以及一些其他團(tuán)隊的人共同維護(hù)的開源項目。當(dāng)應(yīng)用公共狀態(tài)的組件在狀態(tài)發(fā)生變化的時候,會自動完成與狀態(tài)相關(guān)的所有事情,例如自動更新自動緩存數(shù)據(jù),自動通知等。 一、MobX MobX其實(shí)是一個比較輕便的可擴(kuò)展的狀態(tài)管理工具,是一個由Facebook以及一些其他團(tuán)隊的人共同維護(hù)的開源項目。 當(dāng)應(yīng)用公共狀態(tài)的組件在狀態(tài)發(fā)生變化的時候,會自動完...
摘要:需要注意的是,在中,需要把數(shù)據(jù)聲明為。同時還提供了運(yùn)行時的類型安全檢查。在利用了,使異步操作可以在一個函數(shù)內(nèi)完成并且可以被追蹤。例如在中,數(shù)組并不是一個,而是一個類的對象,這是為了能監(jiān)聽到數(shù)據(jù)下標(biāo)的賦值。 Redux是一個數(shù)據(jù)管理層,被廣泛用于管理復(fù)雜應(yīng)用的數(shù)據(jù)。但是實(shí)際使用中,Redux的表現(xiàn)差強(qiáng)人意,可以說是不好用。而同時,社區(qū)也出現(xiàn)了一些數(shù)據(jù)管理的方案,Mobx就是其中之一。 R...
摘要:它是由一個非常聰明的人開發(fā)的,用來緩解在單頁面應(yīng)用中管理狀態(tài)的問題。的問題沒有一種適合所有場景的完美工具。為設(shè)計的是世界的另一個新增內(nèi)容,但目前僅適用于。這將導(dǎo)致最后期限延長,并且留下更多需要我們維護(hù)的代碼。 原文:The Problems with Redux: Can React, MobX, and Realm save us? 作者:Erich Reich 首先,我不討厭 ...
閱讀 1992·2021-11-22 14:45
閱讀 2612·2021-10-12 10:11
閱讀 776·2021-09-22 10:02
閱讀 1233·2019-08-30 15:55
閱讀 1147·2019-08-30 15:54
閱讀 3258·2019-08-30 15:54
閱讀 1196·2019-08-29 17:16
閱讀 3093·2019-08-28 17:55