排查結(jié)果
首先說(shuō)下結(jié)果睦刃,以供參考
github的issue有FlatList不顯示的問(wèn)題,表現(xiàn)的跟我不太一樣十酣,他們解決方案是將removeClippedSubviews={false}
涩拙,我嘗試了一下不適用我的場(chǎng)景
最終找出罪魁禍?zhǔn)资莔obx的observable變量與FlatList的data在release環(huán)境下,未關(guān)閉RN log日志所導(dǎo)致的沖突
- 解決方案1:release環(huán)境關(guān)掉日志(我是用babel的
transform-remove-console
插件來(lái)關(guān)閉的) - 解決方案2:如果一定要開(kāi)日志耸采,F(xiàn)latList的data不要給observable Array兴泥,給普通Array
問(wèn)題描述
首先問(wèn)題如下:
我的RN版本0.54.0
,mobx3.4.1
虾宇,mobx-react4.3.5
一個(gè)長(zhǎng)度為兩百多的數(shù)組只顯示了二十三條郁轻,后面全是空白,繼續(xù)往下劃是一個(gè)無(wú)限空白的list文留,還伴隨著閃屏現(xiàn)象好唯,太可怕,更可怕的是debug包無(wú)此問(wèn)題燥翅,release包卻有骑篙,最怕排查這種問(wèn)題,耗時(shí)耗力
解決思路
當(dāng)時(shí)第一反應(yīng)是沒(méi)做分頁(yè)一次性加載太多數(shù)據(jù)導(dǎo)致的森书,因?yàn)闆](méi)有想到這個(gè)接口會(huì)有這么多數(shù)據(jù)靶端,一般也就十幾二十條,隨即進(jìn)行了分頁(yè)處理凛膏,然而并沒(méi)有什么卵用杨名,仍然是二十三條后就顯示空白,再往后滑動(dòng)閃屏猖毫,此時(shí)也沒(méi)有其他頭緒台谍,這下子只能啃源碼來(lái)看什么原因了,不過(guò)好在FlatList是純js實(shí)現(xiàn)的吁断,不需要再去啃Java代碼了趁蕊。
首先找到FlatList.js文件,看它的render函數(shù)
通過(guò)配置
legacyImplementation
來(lái)選擇使用MetroListView
或者VirtualizedList
前者是老的ListView仔役,后者就是替代老ListView的新列表組件掷伙,官方解釋這個(gè)變量是用來(lái)比較性能的,一般用不著又兵,著重看看VirtualizedList
任柜,view出了問(wèn)題首先就看看renderItem
方法這里就只是區(qū)分了多欄與單欄列表,我的使用場(chǎng)景是單欄列表,這行代碼就只是給FlatList使用者回傳了一個(gè)info參數(shù)宙地,再看看info參數(shù)具體升熊,找到
VirtualizedList
的代碼,再找renderItem
這個(gè)props在哪里調(diào)用的绸栅,可以看到是在
CellRenderer
這個(gè)組件的render方法里調(diào)用的级野,傳入了item,index粹胯,separators
蓖柔,我們要找的就是item,但是item是從props中拿到的风纠,再找找CellRenderer
在哪里使用况鸣,可以看到是在_pushCells
方法中使用,_pushCells
方法在VirtualizedList
的render方法中調(diào)用竹观,cells作為
React.cloneElement(element,[props],[...children])
的第三參數(shù)镐捧,如上圖代碼,此時(shí)基本可以確定問(wèn)題應(yīng)該在這個(gè)cells
參數(shù)上了臭增,再回頭看看_pushCells
方法可以看到item數(shù)據(jù)是來(lái)自props的
getItem
方法懂酱,這個(gè)方法傳入了一個(gè)data和一個(gè)ii下標(biāo),顧名思義應(yīng)該就是在取單個(gè)列表的渲染數(shù)據(jù)誊抛,這個(gè)data就是FlatList的data列牺,我們的列表數(shù)據(jù)源,再回到調(diào)用方FlatList找到getItem
方法這個(gè)方法只是對(duì)多欄和單欄列表取數(shù)據(jù)的邏輯做了區(qū)分拗窃,我們可以試著把取出來(lái)的數(shù)據(jù)打印出來(lái)看是否有異常瞎领,加好調(diào)試代碼,再編譯一個(gè)帶log的release包
可以看到第23個(gè)都挺正常随夸,到了24個(gè)就不正常了九默,到了28個(gè)直接拋出error了,加了調(diào)試日志之后還會(huì)crash了宾毒,所以這個(gè)數(shù)據(jù)源可能有問(wèn)題驼修,聯(lián)想到我用的Mobx框架,傳給data的是一個(gè)Observable Array伍俘,而非普通Array邪锌,猜測(cè)是Observable Array與FlatList在此環(huán)境下有沖突,隨后將其替換成普通Array癌瘾,然后打包,測(cè)試一切正常
結(jié)尾
當(dāng)時(shí)得出結(jié)論是FlatList和Observable Array搭配使用就會(huì)在release環(huán)境出問(wèn)題饵溅,但是如果是這種結(jié)果妨退,那問(wèn)題影響面就太大了,然后發(fā)現(xiàn)我打的release包為了方便定位bug,將transform-remove-console
這個(gè)插件屏蔽了咬荷,打開(kāi)了js日志冠句。隨后我又試著關(guān)閉日志,F(xiàn)latList繼續(xù)使用Observable Array幸乒,然后打包懦底,測(cè)試一切正常,然后就經(jīng)過(guò)了幾番測(cè)試罕扎,基本確認(rèn)了問(wèn)題所在聚唐,實(shí)在有點(diǎn)玄學(xué),為了定位這一個(gè)bug腔召,打了快一天的包杆查。。當(dāng)然結(jié)論不重要臀蛛,重要的是解決問(wèn)題過(guò)程亲桦,以后再遇到這種問(wèn)題,解決起來(lái)應(yīng)該更加得心應(yīng)手