在React Native 中由于业务的需要, 我们往往要在诸多的页面间,组件之间做一些参数的传递与管理, 在这里我总结了几大经过验证,稳定好用的方式给大家

React Navigation 导航传值

推荐指数: "htmlcode">

 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"htmlcode">
'data in callback: ', { id: '123', message: 'list really"color: #ff0000">DeviceEventEmitter 触发事件并传值

推荐指数: "htmlcode">

 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

缺点: 本质是对自定义事件的监听与触发, 当页面逻辑复杂时,代码会相对变大, 维护成本变高, 且监听过多会造成性能问题, 还有一点就是在页面销毁时必须移除监听: 如果忘记移除监听会怎么样"htmlcode">

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

个人建议: 在梳理清楚页面逻辑后,合理使用

AsyncStorage Key-Value 式的存储传参

推荐指数: "htmlcode">

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)

推荐指数: "htmlcode">

 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项目的开发带来更为理想的效果,感谢您的阅读,也希望大家多多支持。

广告合作:本站广告合作请联系QQ:858582 申请时备注:广告合作(否则不回)
免责声明:本站资源来自互联网收集,仅供用于学习和交流,请遵循相关法律法规,本站一切资源不代表本站立场,如有侵权、后门、不妥请联系本站删除!

稳了!魔兽国服回归的3条重磅消息!官宣时间再确认!

昨天有一位朋友在大神群里分享,自己亚服账号被封号之后居然弹出了国服的封号信息对话框。

这里面让他访问的是一个国服的战网网址,com.cn和后面的zh都非常明白地表明这就是国服战网。

而他在复制这个网址并且进行登录之后,确实是网易的网址,也就是我们熟悉的停服之后国服发布的暴雪游戏产品运营到期开放退款的说明。这是一件比较奇怪的事情,因为以前都没有出现这样的情况,现在突然提示跳转到国服战网的网址,是不是说明了简体中文客户端已经开始进行更新了呢?