React Native 傳參的五種方式

在React Native 中因爲業務的須要, 咱們每每要在諸多的頁面間,組件之間作一些參數的傳遞與管理, 在這裏我總結了幾大通過驗證,穩定好用的方式給你們react

React Navigation 導航傳值

推薦指數: ♥ ♥ ♥ ♥ ♥
適用範圍: 相鄰頁面間傳值
兼容性: IOS/Android
原理: React Navigation 爲頁面的 props 上掛載了 navigation 對象, 可用來作路由跳轉,在作頁面跳轉時能夠攜帶參數/回調方法前往目標頁面, 從而達到傳參的目的
說明: 這是官方推薦,也是咱們在業務開發中用得最多,最爲推崇的一種傳參方式, 思想與 web 在 querystring 上帶參跳轉相似,只是實現方式略微不一樣, 舉例:web

導航傳值便可正向傳值,也可反向傳值 例如 A->B 是正向傳值, 而B->A 則是反向傳值
 正向傳值:
  A頁面跳轉向B頁面, 在組件內經過訪問 this.props.navigation.navigate('B', { 
   type: 'list',         
   callback:data => { console.log('data in callback: ', data); }
  });
  
 在B頁面 就能在組件的生命週期函數中拿到值
  componentWillMount() {
    const { state: { params: { type, callback }, goBack }} = this.props.navigation;
    console.log('type: ', type);
    // type 'list'
  }

 反向傳值: 在反回前一個頁面時, 手動調用callback,並給其傳參, 再調用 goBack 方法, 便可達到目的。
 仍是上面的例子:
 當從B返回A的時候
 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 參數就是 { id: '123', message: 'list really?'}

DeviceEventEmitter 觸發事件並傳值

推薦指數: ♥ ♥ ♥ ♥
適用範圍: 頁面間傳值/組件間傳值
兼容性: IOS/Android
原理: 利用 React Native 包中提供的 DeviceEventEmitter 模塊訂閱事件,觸發事件,同時傳值
說明: DeviceEventEmitter 從名字就能知道他是基於事件訂閱的機制來進行傳值的, 當訂閱某種事件後, 觸發的時候會調用訂閱事件的回調, 並能把值傳送過去, 而且在同頁面內的組間件, 不一樣頁面間均可以傳值, 但前提是頁面還未被銷燬(銷燬後事件的訂閱會取消), 例如:數組

DeviceEventEmitter.addListener('warning_event', (data) => { console.log('data: ', data);})
  DeviceEventEmitter.emit('warning_event', { name: 'Mega Galaxy'});
  //  data: { name: 'Mega Galaxy' }

  在emit(觸發)事件後, 回調函數的入參就變成了咱們所傳遞的 { name: 'Mega Galaxy'}, 
  也可不傳值,不傳值時 callback 的入參就是 undefined

缺點: 本質是對自定義事件的監聽與觸發, 當頁面邏輯複雜時,代碼量會增多, 維護成本變高, 且監聽過多會形成性能問題, 還有一點就是在頁面銷燬時必須移除監聽: 若是忘記移除監聽會怎麼樣? 那每當 emit 事件一次, 就會多響應一次你加上去的監聽app

componentDidMount() {
    this.eventHandler = DeviceEventEmitter.addListner('event_name', callback);
}
componentWillUnmount() {
    this.eventHandler.remove();
}

我的建議: 在梳理清楚頁面邏輯後,合理使用異步

AsyncStorage Key-Value 式的存儲傳參

推薦指數: ♥ ♥ ♥ ♥
適用範圍: 跨頁面 跨組件的任性傳參
兼容性: IOS/Android
原理: 利用相似 web 中 localStorage 的思想,將參數/數據存放在 AsyncStorage中,在須要的地方再取出來
說明: localStorage 在 web 中的實用性 與 受歡迎程度你們是知道的, AsyncStorage其實就是 rn 版的 localStorage, 略微不一樣的是它是異步的,只返回 Promise, 因此與 async/await 結合會很是好用async

···ide

在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 });
}

缺點: 以 Key-Value 式的存儲傳參,可能重點仍是在數據存儲上, 且由於涉及到 I/O 的操做,在部份低端機型上,有卡頓的可能性函數

React Context Api 傳參(新版Context Api)

推薦指數: ♥ ♥ ♥
適用範圍: 不一樣頁面內的組件共享公共類的數據
兼容性: IOS/Android
原理: 利用生成的數據倉庫包裹父級組件, 再從子組件中獲取數據倉庫中的數據
說明: Context Api 在管理登陸用戶數據這類具備公共屬性的數據是一把利器, 但使用起來會至關繁瑣性能

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>
  會渲染成 <Text> Mega Galaxy FrontEnd Engineer </Text>

缺點: 理解須要花一些功夫, 寫法繁瑣,且只適合特定類型的數據,要明確組件間的包裹關係this

Global 傳值

推薦指數: ♥ ♥ ♥
適用範圍: 頁面間傳值(全局任意頁面)
兼容性: IOS/Android
原理: 利用 Node.js 中的頂級對象 -- Global. 來掛載屬性, 利用屬性傳值
說明: 在跳轉的頁面前,能夠把須要傳遞的參數掛載在 Global 對象上, 在跳轉後便可在 Global 對象上訪問鍵取到對應的值, 例如:

在 A 頁面:
    Global.params = { name: 'Jalon', id: '123456'}, 
跳轉任意頁面後:
    Global.params // { name: 'Jalon', id: '123456'}

除了字值串,布爾值,對象 和 數組, 也能夠傳遞函數, 
若是傳遞的函數有引用組件上下文環境的變量,注意解耦,不然可能會報錯.

缺點: 若是掛載的屬性/方法過多 易形成衝突與污染, 不利於維護
我的建議: 在 react-navigation 跳轉傳值 與 DeviceEventEmitter 維護不方便的狀況下才使用, 但儘可能少用, 以避免形成全局屬性的污染與衝突

總結了5種常見的參數/數據傳遞的方法,以我的角度來看, 推薦順序爲 React Navigation 導航傳值 > DeviceEventEmitter 觸發事件並傳值 > AsyncStorage Key-Value 式的存儲傳參, 最後 兩種是在特殊場景下才會去使用,因此在合適的場景去選擇合適的方式傳值,會爲React Native項目的開發帶來事半功倍的效果.

相關文章
相關標籤/搜索