淺談React Native 傳參的幾種方式(小結(jié))
在React Native 中由于業(yè)務(wù)的需要, 我們往往要在諸多的頁面間,組件之間做一些參數(shù)的傳遞與管理, 在這里我總結(jié)了幾大經(jīng)過驗(yàn)證,穩(wěn)定好用的方式給大家
React Navigation 導(dǎo)航傳值
推薦指數(shù): ♥ ♥ ♥ ♥ ♥
適用范圍: 相互跳轉(zhuǎn)的頁面間傳值
兼容性: IOS/Android
原理: React Navigation 為頁面的 props 上掛載了 navigation 對(duì)象, 可用來做路由跳轉(zhuǎn),在做頁面跳轉(zhuǎn)時(shí)可以攜帶參數(shù)/回調(diào)方法前往目標(biāo)頁面, 從而達(dá)到傳參的目的
說明: 這是官方推薦,也是我們?cè)跇I(yè)務(wù)開發(fā)中用得最多,最為推崇的一種傳參方式, 思想與 web 在 querystring 上帶參跳轉(zhuǎn)類似,只是實(shí)現(xiàn)方式略微不同, 舉例
導(dǎo)航傳值即可正向傳值,也可反向傳值 例如 A->B 是正向傳值, 而B->A 則是反向傳值
正向傳值:
A頁面跳轉(zhuǎn)向B頁面, 在組件內(nèi)通過訪問 this.props.navigation.navigate('B', {
type: 'list', callback:data => { console.log('data in callback: ', data); } });
在B頁面 就能在組件的生命周期函數(shù)中拿到值
componentWillMount() { const { state: { params: { type, callback }, goBack }} = this.props.navigation; console.log('type: ', type); // type 'list' }
反向傳值: 在反回上一個(gè)頁面時(shí), 手動(dòng)調(diào)用callback, 并給其傳參, 再調(diào)用 goBack 方法, 即可達(dá)到目的
還是上面的例子:
當(dāng)從B返回A的時(shí)候
goBackToPageA: () => { const { state: { params: { type, callback }, goBack }} = this.props.navigation; callback({ id: '123', message: type + ' really?'}); goBack(); } goBackToPageA();
回到A頁面后
'data in callback: ', { id: '123', message: 'list really?'});
也即callBack 中的 data 參數(shù)就是 { id: '123', message: 'list really?'}
DeviceEventEmitter 觸發(fā)事件并傳值
推薦指數(shù): ♥ ♥ ♥ ♥
適用范圍: 頁面間傳值/組件間傳值
兼容性: IOS/Android
原理: 利用 React Native 包中提供的 DeviceEventEmitter 模塊訂閱事件,觸發(fā)事件,并能同時(shí)傳值
說明: DeviceEventEmitter 從名字就能知道他是基于事件訂閱的機(jī)制來進(jìn)行傳值的, 當(dāng)訂閱某種事件后, 觸發(fā)的時(shí)候會(huì)調(diào)用訂閱事件的回調(diào), 并能把值傳送過去, 并且在同頁面內(nèi)的組間件, 不同頁面間都可以傳值, 但前提是頁面還未被銷毀(銷毀后事件的訂閱會(huì)取消), 例如:
DeviceEventEmitter.addListener('warning_event', (data) => { console.log('data: ', data);}) DeviceEventEmitter.emit('warning_event', { name: 'Mega Galaxy'}); // data: { name: 'Mega Galaxy' }
在emit(觸發(fā))事件后, 回調(diào)函數(shù)的入?yún)⒕妥兂闪宋覀兯鶄鬟f的 { name: 'Mega Galaxy'},
也可不傳值,不傳值時(shí) callback 的入?yún)⒕褪?undefined
缺點(diǎn): 本質(zhì)是對(duì)自定義事件的監(jiān)聽與觸發(fā), 當(dāng)頁面邏輯復(fù)雜時(shí),代碼會(huì)相對(duì)變大, 維護(hù)成本變高, 且監(jiān)聽過多會(huì)造成性能問題, 還有一點(diǎn)就是在頁面銷毀時(shí)必須移除監(jiān)聽: 如果忘記移除監(jiān)聽會(huì)怎么樣? 那emit 一次的時(shí)候, 會(huì)多響應(yīng)一次你加上去的監(jiān)聽
componentDidMount() { this.eventHandler = DeviceEventEmitter.addListner('event_name', callback); } componentWillUnmount() { this.eventHandler.remove(); }
個(gè)人建議: 在梳理清楚頁面邏輯后,合理使用
AsyncStorage Key-Value 式的存儲(chǔ)傳參
推薦指數(shù): ♥ ♥ ♥ ♥
適用范圍: 跨頁面 跨組件的任性傳參
兼容性: IOS/Android
原理: 利用類似 web 中 localStorage 的思想,將參數(shù)/數(shù)據(jù)存放在 AsyncStorage中,在需要的地方再取出來
說明: localStorage 在 web 中的實(shí)用性 與 受歡迎程度大家是知道的, AsyncStorage其實(shí)就是 rn 版的 localStorage, 略微不同的是它是異步的,只返回 Promise, 所以與 async/await 結(jié)合會(huì)非常好用
···
在A頁面
saveOrderData = async () => { try { const orderData = [{ id: 1, data: []}, { id: 2, data: []}] await AsyncStorage.setItem('Order_data_cache', JSON.stringify(orderData )); } catch (error) { // Error saving data } }
在B頁面
loadOrderData = async () => { const __orderData = await AsyncStorage.getItem('Order_data_cache'); const orderData = JSON.parse(__orderData); this.setState({ orderData }); }
缺點(diǎn): 以 Key-Value 式的存儲(chǔ)傳參,可能重點(diǎn)還是在數(shù)據(jù)存儲(chǔ)上, 且因?yàn)樯婕暗?I/O 的操作,在部份低端機(jī)型上,有卡頓的可能性
React Context Api 傳參(新版Context Api)
推薦指數(shù): ♥ ♥ ♥
適用范圍: 不同頁面間的組件共享公共類的數(shù)據(jù)
兼容性: IOS/Android
原理: 利用生成的數(shù)據(jù)倉庫包裹父級(jí)組件, 再從子組件中獲取數(shù)據(jù)倉庫中的數(shù)據(jù)
說明: Context Api 在管理登錄用戶數(shù)據(jù)這類具有公共屬性的數(shù)據(jù)是一把利器, 但使用起來會(huì)相當(dāng)繁瑣
const ContextWrapper = React.createContext(); <ContextWrapper.Provider value={{ name: 'Mega Galaxy', job: 'FrontEnd Engineer' }} <App /> <ContextWrapper.Provider> // 注意這里的 <App /> 是指我們 App的根組件,在包裹根組件后 我們可以在任意子頁面組件 中取值
任意 <App /> 里的子頁面組件中
<ContextWrapper.Counsumer> { context => <Text> { context.name } { context.job }</Text> } </ContextWrapper.Counsumer> 會(huì)渲染成 <Text> Mega Galaxy FrontEnd Engineer </Text>
缺點(diǎn): 理解需要花一些功夫, 寫法繁瑣,且只適合特定類型的數(shù)據(jù),要明確組件間的包裹關(guān)系
Global 傳值
推薦指數(shù): ♥ ♥ ♥
適用范圍: 頁面間傳值
兼容性: IOS/Android
原理: 利用 Node.js 中的頂級(jí)對(duì)象 Global 來掛載屬性, 利用屬性傳值
說明: 在跳轉(zhuǎn)的頁面前,可以把需要傳遞的參數(shù)掛載在 Global 對(duì)象上, 在跳轉(zhuǎn)后即可在 Global 對(duì)象上取過相同的鍵取到對(duì)應(yīng)的值, 例如: 在 A 頁面跳轉(zhuǎn) B 頁面時(shí), Global.params = { name: 'Jalon', id: '123456'}, 在跳轉(zhuǎn)之后, 即可通過 Global.params 拿到值, 除了普通的字值串,布爾值,對(duì)象,數(shù)組, 也可以傳遞函數(shù), 但要注意帶有 this.setState 方法的函數(shù)傳遞后 調(diào)用可能會(huì)報(bào)錯(cuò).
缺點(diǎn): 如果掛載的屬性/方法過多 易造成沖突與污染, 不利于維護(hù)
個(gè)人建議: 在 react-navigation 跳轉(zhuǎn)傳值 與 DeviceEventEmitter 維護(hù)不方便的情況下才使用, 但盡量少用, 以免造成 Global 屬性的污染與沖突
總結(jié)了5種常見的參數(shù)/數(shù)據(jù)傳遞的方法,以個(gè)人角度來看, 推薦順序?yàn)?React Navigation 導(dǎo)航傳值 > DeviceEventEmitter 觸發(fā)事件并傳值 > AsyncStorage Key-Value 式的存儲(chǔ)傳參, 最后 兩種是在特殊場(chǎng)景下才會(huì)去使用,所以朋友們,在合適的場(chǎng)景選擇合適的方式去傳值,會(huì)為React Native項(xiàng)目的開發(fā)帶來更為理想的效果,感謝您的閱讀,也希望大家多多支持腳本之家。
相關(guān)文章
在React中強(qiáng)制重新渲染的4 種方式案例代碼
這篇文章主要介紹了在React中強(qiáng)制重新渲染的4 種方式,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友參考下吧2023-12-12React Hook - 自定義Hook的基本使用和案例講解
自定義Hook本質(zhì)上只是一種函數(shù)代碼邏輯的抽取,嚴(yán)格意義上來說,它本身并不算React的特性,這篇文章主要介紹了React類組件和函數(shù)組件對(duì)比-Hooks的介紹及初體驗(yàn),需要的朋友可以參考下2022-11-11react-native 配置@符號(hào)絕對(duì)路徑配置和絕對(duì)路徑?jīng)]有提示的問題
本文主要介紹了react-native 配置@符號(hào)絕對(duì)路徑配置和絕對(duì)路徑?jīng)]有提示的問題,文中通過圖文示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2024-01-01React Antd中如何設(shè)置表單只輸入數(shù)字
這篇文章主要介紹了React Antd中如何設(shè)置表單只輸入數(shù)字問題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-06-06react?事項(xiàng)懶加載的三種方法及使用場(chǎng)景
這篇文章主要介紹了react?事項(xiàng)懶加載的三種方法及使用場(chǎng)景,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2023-07-07解析TypeError:import_react_native.AppState.removeEventListener
這篇文章主要為大家介紹了TypeError:import_react_native.AppState.removeEventListener?is?not?a?function問題解決分析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-09-09React實(shí)現(xiàn)Excel文件的導(dǎo)出與在線預(yù)覽功能
這篇文章主要為大家詳細(xì)介紹了如何利用?React?18?的強(qiáng)大功能,演示如何使用?React?18?編寫?Excel?文件的導(dǎo)出與在線預(yù)覽功能,需要的小伙伴可以參考下2023-12-12