最近在項(xiàng)目中引入了React Native,在開發(fā)過(guò)程中遇到了不少問(wèn)題湿故。其中l(wèi)istView的刷新機(jī)制和子組件的刷新問(wèn)題尤為頭痛蟆炊,在此記錄一下稽莉。
一、ListView的刷新機(jī)制
在RN中加入一個(gè)ListView組件時(shí)涩搓,你需要指定ListView的datasource即數(shù)據(jù)來(lái)源污秆。一般我們會(huì)在構(gòu)造函數(shù)中設(shè)置ListView的datasource:
其中dataBlob是字典嵌套的數(shù)組類似于:{key1:[row1, row2, row3], key2: [row1, row2],...},sectionIdArr是所有key的數(shù)組[key1, key2,...]昧甘。若不需要section時(shí)dataBlob可以使用純數(shù)組[row1, row2, row3,...]混狠。
而其中非常重要的兩個(gè)函數(shù)rowHasChanged(r1, r2)、sectionHeaderHasChanged(r1, r2)指定了什么時(shí)候調(diào)用renderRow()和renderSectionHeader()來(lái)刷新ListView疾层。
rowHasChanged: (r1, r2)=> r1!==r2
意思是當(dāng)rowdata發(fā)生改變時(shí)調(diào)用renderRow()将饺。這樣你重新給state里的dataSource賦值時(shí)就會(huì)調(diào)用ListView的renderRow()了。
在這里你必須注意一點(diǎn):不可以在原有的dataBlob上修改痛黎,如下操作是不會(huì)觸發(fā)renderRow()的:
推薦使用JSON.parse(JSON.stringify(dataMap))來(lái)返回一個(gè)新的dataBlob予弧,這樣可以簡(jiǎn)單有效的觸發(fā)renderRow()的:
二、子組件的刷新與state問(wèn)題
1湖饱、刷新問(wèn)題
與圖所示掖蛤,若我們?cè)贚istView上加一個(gè)選擇按鈕,點(diǎn)擊會(huì)有選中效果井厌。有兩種做法蚓庭,一種直接加一個(gè)Image在row上面,并在rowdata里面加入一個(gè)select字段來(lái)記錄選中狀態(tài)仅仆,點(diǎn)擊時(shí)改變ListView的Datasource來(lái)刷新這個(gè)image器赞。不過(guò)這樣會(huì)很麻煩,要改變datasource墓拜,要重新調(diào)用reder()港柜,這樣改變一個(gè)按鈕狀態(tài)會(huì)重刷整個(gè)界面相當(dāng)不合理。第二種做法就是新建一個(gè)組件在組件里做這些操作。下面就說(shuō)一下第二種方法
我們新建一個(gè)組件叫Button.js:
并在父組件里調(diào)用Button組件:
這樣點(diǎn)擊的時(shí)候按鈕就會(huì)切換狀態(tài)夏醉,并調(diào)用父組件的selectAll返回爽锥。而且不需要再父組件里重刷界面。
2畔柔、state問(wèn)題
如果現(xiàn)在有個(gè)新需求氯夷,在刷新界面是要保持選中狀態(tài),要如何去做呢靶擦?我們要了解肠槽,當(dāng)組件已經(jīng)加載過(guò)后,父組件重新render()時(shí)奢啥,子組件是不會(huì)重新調(diào)用constructor的秸仙。不過(guò)這時(shí)他們觸發(fā)componentWillUpdate方法,我們只要在這里重新給Button的state賦值就可以了:
并且在刷新的時(shí)候給button的props將seletcted傳遞過(guò)去就可以了桩盲。
三寂纪、結(jié)語(yǔ)
學(xué)習(xí)新技術(shù)的過(guò)程中難免會(huì)遇到這樣那樣的坑和難題,不過(guò)只有這樣人才能成長(zhǎng)和進(jìn)步赌结,本文記錄總結(jié)了本人在使用RN的過(guò)程中遇到的一些問(wèn)題捞蛋。希望能給別的有點(diǎn)小小的幫助,文章中如有錯(cuò)誤或紕漏還望不吝賜教柬姚。