资讯专栏INFORMATION COLUMN

React Native 传参的五种方式

cnTomato / 2022人阅读

摘要:在中由于业务的需要我们往往要在诸多的页面间,组件之间做一些参数的传递与管理在这里我总结了几大经过验证,稳定好用的方式给大家导航传值推荐指数适用范围相邻页面间传值兼容性原理为页面的上挂载了对象可用来做路由跳转,在做页面跳转时可以携带参数回调方

在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();
  
  
  // 注意这里的  是指我们 App的根组件,在包裹根组件后 我们可以在任意子页面组件 中取值

  任意  里的子页面组件中

   
    { context =>  { context.name } { context.job } }
  
  会渲染成  Mega Galaxy FrontEnd Engineer 

缺点: 理解需要花一些功夫, 写法繁琐,且只适合特定类型的数据,要明确组件间的包裹关系

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项目的开发带来事半功倍的效果.

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/109704.html

相关文章

  • 2017-07-18 前端日报

    摘要:前端日报精选常用实例的实现与封装实现一个构建基于的可扩展应用规范翻译从到中文开源中国两级缓存实践掘金中基于的自动实体类构建与接口文档生成某熊的全栈之路继承总结教程中的五种组件形式掘金再说的问题前端开发前端每周清单第期正式 2017-07-18 前端日报 精选 javascript常用实例的实现与封装实现一个 SwiperRekit 2.0 构建基于React+Redux+React-r...

    lauren_liuling 评论0 收藏0
  • Flow - JS静态类型检查工具

    摘要:介绍是个的静态类型检查工具,由出品的开源码项目,问世只有一年多,是个相当年轻的项目。现在,提供了另一个新的选项,它是一种强静态类型的辅助检查工具。 showImg(https://segmentfault.com/img/bVH6mL?w=1200&h=675); 本章的目标是提供一些Flow工具的介绍与使用建议。Flow本质上也只是个检查工具,它并不会自动修正代码中的错误,也不会强制...

    seanHai 评论0 收藏0
  • 手挽手带你学React:三档 React-router4.x的使用

    摘要:我们在内部来渲染不同的组件我们这里采用哈希路由的方式,鉴于的渲染机制,我们需要把值绑定进入内部。 手挽手带你学React入门三档,带你学会使用Reacr-router4.x,开始创建属于你的React项目 什么是React-router React Router 是一个基于 React 之上的强大路由库,它可以让你向应用中快速地添加视图和数据流,同时保持页面与 URL 间的同步。通俗一...

    SunZhaopeng 评论0 收藏0
  • 初识React(8):父子组件传参

    摘要:父级向子级传参父子组件通信主要用到,如下在父组件中父组件我是父级过来的内容在子组件中子组件通过上面例子可以看出,在父组件中,我们引入子组件,通过给子组件添加属性,来起到传参的作用,子组件可以通过获取父组件传过来的参数子级向父级传参在父组件中 父级向子级传参 父子组件通信主要用到props,如下: 在父组件中: import React from react import ChildCo...

    paulli3 评论0 收藏0
  • 组织优化云计算使用五种方式

    摘要:根据市场研究机构科技商业研究公司的调查年公共云计算的市场规模约为亿美元。云计算的成本将继续下降人们可能已经知道云计算的性能变得越来越好。毕竟绝大多数云计算使用案例仍然是基础设施即服务。如今,IT行业人士都知道一个道理:当谈到云计算和数据中心的发展趋势时,没有现状这一说法,因为其发展不是每年或每月的变化,它们似乎每分钟都在发生变化。根据市场研究机构科技商业研究(TBR) 公司的调查,2010年...

    rottengeek 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<