在React Native 中由于业务的需要, 我们往往要在诸多的页面间,组件之间做一些参数的传递与管理, 在这里我总结了几大经过验证,稳定好用的方式给大家
React Navigation 导航传值
推荐指数: ♥ ♥ ♥ ♥ ♥
适用范围: 相互跳转的页面间传值
兼容性: IOS/Android
原理: React Navigation 为页面的 props 上挂载了 navigation 对象, 可用来做路由跳转,在做页面跳转时可以携带参数/回调方法前往目标页面, 从而达到传参的目的
说明: 这是官方推荐,也是我们在业务开发中用得最多,最为推崇的一种传参方式, 思想与 web 在 querystring 上带参跳转类似,只是实现方式略微不同, 举例
导航传值即可正向传值,也可反向传值 例如 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 一次的时候, 会多响应一次你加上去的监听
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 结合会非常好用
···
在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>
缺点: 理解需要花一些功夫, 写法繁琐,且只适合特定类型的数据,要明确组件间的包裹关系
Global 传值
推荐指数: ♥ ♥ ♥
适用范围: 页面间传值
兼容性: IOS/Android
原理: 利用 Node.js 中的顶级对象 Global 来挂载属性, 利用属性传值
说明: 在跳转的页面前,可以把需要传递的参数挂载在 Global 对象上, 在跳转后即可在 Global 对象上取过相同的键取到对应的值, 例如: 在 A 页面跳转 B 页面时, Global.params = { name: 'Jalon', id: '123456'}, 在跳转之后, 即可通过 Global.params 拿到值, 除了普通的字值串,布尔值,对象,数组, 也可以传递函数, 但要注意带有 this.setState 方法的函数传递后 调用可能会报错.
缺点: 如果挂载的属性/方法过多 易造成冲突与污染, 不利于维护
个人建议: 在 react-navigation 跳转传值 与 DeviceEventEmitter 维护不方便的情况下才使用, 但尽量少用, 以免造成 Global 属性的污染与冲突
总结了5种常见的参数/数据传递的方法,以个人角度来看, 推荐顺序为 React Navigation 导航传值 > DeviceEventEmitter 触发事件并传值 > AsyncStorage Key-Value 式的存储传参, 最后 两种是在特殊场景下才会去使用,所以朋友们,在合适的场景选择合适的方式去传值,会为React Native项目的开发带来更为理想的效果,感谢您的阅读,也希望大家多多支持小牛知识库。
本文向大家介绍Mybatis的几种传参方式详解,包括了Mybatis的几种传参方式详解的使用技巧和注意事项,需要的朋友参考一下 前言 前几天恰好面试一个应届生,问了一个很简单的问题:你了解过Mybatis中有几种传参方式吗? 没想到其他问题回答的很好,唯独这个问题一知半解,勉强回答了其中两种方式。 于是这篇文章就来说一说Mybatis传参的几种常见方式,给正在面试或者准备面试的朋友巩固一下。 单个
本文向大家介绍浅谈JackSon的几种用法,包括了浅谈JackSon的几种用法的使用技巧和注意事项,需要的朋友参考一下 JackSon介绍 本文使用的JackSon版本为2.9.6。 JackSon是解析JSON和XML的一个框架,优点是简单易用,性能较高。 JackSon处理JSON的方式 JackSon提供了三种JSON的处理方式。分别是数据绑定,树模型,流式API。下面会分别介绍这三种方式。
本文向大家介绍浅谈RxJava处理业务异常的几种方式,包括了浅谈RxJava处理业务异常的几种方式的使用技巧和注意事项,需要的朋友参考一下 本文介绍了RxJava处理业务异常的几种方式,分享给大家。具体如下: 关于异常 Java的异常可以分为两种:运行时异常和检查性异常。 运行时异常: RuntimeException类及其子类都被称为运行时异常,这种异常的特点是Java编译器不去检查它,也就是说
本文向大家介绍浅谈JS中几种轻松处理'this'指向方式,包括了浅谈JS中几种轻松处理'this'指向方式的使用技巧和注意事项,需要的朋友参考一下 我喜欢在JS中更改函数执行上下文的指向,也称为 this 指向。 例如,咱们可以在类数组对象上使用数组方法: 另一方面,this 很难把握。 咱们经常会发现自己用的 this 指向不正确。下面的教你如何简单地将 this 绑定到所需的值。 在开始之前,
本文向大家介绍浅谈几种常用的JS类定义方法,包括了浅谈几种常用的JS类定义方法的使用技巧和注意事项,需要的朋友参考一下 // 方法1 对象直接量 // 方法2 定义函数对象 // 方法3 原型继承 // 方法4 工厂模式 以上这篇浅谈几种常用的JS类定义方法就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持呐喊教程。
本文向大家介绍Python传递参数的多种方式(小结),包括了Python传递参数的多种方式(小结)的使用技巧和注意事项,需要的朋友参考一下 一 位置传递 没什么好过多讲解. 输出: 6 二 关键字传递 更具每个参数的名字写入函数参数 输出: 6 三 参数默认值传递 给函数的输入参数设定一个默认值,如果该参数最终没有输入,则使用默认参数出入函数. 输出: 6 四 包裹传递 在定义函数时,我们有时