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