博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
React Native 解决 Navigator.pop 无法传参数
阅读量:6074 次
发布时间:2019-06-20

本文共 3287 字,大约阅读时间需要 10 分钟。

紧接着上一篇文章 当时扫是扫了,东西是出来了,但是并没有做界面返回,而自带的 navigator.pop 方法又没有参数传递,那不是白扫了吗?

封装 Navigator

好吧, 这步其实和下面讲的没有什么关系,不过为了看下面内容的时候不会混淆,这里还是简单说下。

React Native 提供了两个导航组件,NavigatorIOS 和 Navigator。 NavigatorIOS 封装程度比较高,比较好用,但是只能在 iOS 上用,Navigator 相对封装程度比较低,但是为了以后能方便的给 Android 用,我们还是封装一下 Navigator。

'use strict';import React, {Component} from 'react';import {    View,    Text,    ScrollView,    StyleSheet,    Navigator} from 'react-native';export default class Navigation extends Component {    render() {        return (            
{ return Navigator.SceneConfigs.FloatFromBottom; } } renderScene = {(route, navigator) => { const RouteComponent = route.component; return (
) }} /> ) }}复制代码

这里使用了 {...route.passProps} 是为了保持和 NavigatorIOS 一样的接口,这里转场动画规定了用从下到上弹出的方式,可以在 configureScene = { ()=>{ return Navigator.SceneConfigs.FloatFromBottom; } } 这里修改。

后面的 this.props.navigator 就是从 navigator={navigator} 这里来的。

调用的时候还有一点要注意,千万不要在 Navigator 外面包任何的 View 或者别的什么,会报错。

index.ios.js中调用:

render() {    return (          
); }复制代码

方法一 -- 使用回调

利用 passProps 传一个 callback 函数进去。

调用的地方,book_list.js:

_changeText(val) {        this.setState({            keywords:val        })    }    _scan(){        this.props.navigator.push({            component: ScanView,            passProps: {                navigator: this.props.navigator,                callback: this._changeText            }        })    }复制代码

这里的 this._changeText 换成一个匿名函数也可以。

返回的地方,scan_view.js:

_show(val) {        this.setState({            code:val.data        })        // Use navigator pop        if( this.props.callback ){            this.props.callback(val.data)        }        if( this.props.navigator ){            this.props.navigator.pop();        }    }复制代码

通过页面加回调函数的确可以解决这个问题,但是如果有多个页面要用到我扫描的数据,那我除了要在用到扫描数据本身的 View 里面做逻辑,在扫描这个 View 里面也要做逻辑,每多一个地方要传数据,就多一个回调函数。直觉告诉我,这很坑爹。

方法二 -- 使用 DeviceEventEmitter

DeviceEventEmitter 是 React Native 提供的,在 Native 和 JavaScript 之间传递消息用的。类似一个发布订阅模式,由 DeviceEventEmitter.emit 来发布消息,需要用到的地方使用 DeviceEventEmitter.addListener 来订阅消息。

调用的地方,book_list.js:

componentDidMount() {        this.subscription = DeviceEventEmitter.addListener('finishScan',this._changeText);    }    componentWillUnmount() {        this.subscription.remove();    }复制代码

注意,这里我们订阅消息是在组件 mount 之后,同时我们需要在合适的时候手动取消订阅 this.subscription.remove(); 否则可能会导致内存泄露。

返回的地方,scan_view.js:

_show(val) {        this.setState({            code:val.data        })        // Use DeviceEventEmitter        DeviceEventEmitter.emit('finishScan',val.data);        if( this.props.navigator ){            this.props.navigator.pop();        }    }复制代码

这里就是当我们扫描到东西,就触发一个叫 finisScan 的事件,并退出当前 View,在 book_list.js 中就可以收到这个事件,并做相应处理。如果有别的地方需要用到扫描的数据,直接订阅这个事件就可以了,在 scan_view.js 中不需要额外的处理。

在调试过程中,还遇到一个问题 A valid provisioning profile for this executable was not found

大意就是证书没了,打开我的调试设备 iPad,通用-描述文件与设备管理 果然上周做扫描的时候用的证书没了,Xcode 打开项目,找到签名证书那里,原来这种测试证书是有期限的,一个星期,刚好刚才过期了。重新点一下又可以获得七天的 buff 了。

总结

有时候当你意识到用了一种不好的方法实现了某个功能的时候,你需要去寻找寻找是否有更优雅的方法,毕竟人生已经如此的艰难,不要为自己挖坑。

碎碎念

最近总想记录一些所思所想,写写科技与人文,写写生活状态,写写读书感悟,主要是扯淡和感悟,欢迎关注,交流。

微信公众号:程序员的诗和远方

公众号ID : MonkeyCoder-Life

参考

转载地址:http://gbigx.baihongyu.com/

你可能感兴趣的文章
2016/4/19 反射
查看>>
SharePoint Wiki发布页面的“保存冲突”
查看>>
oracle 10g 数据库与客户端冲突导致实例创建无监听问题
查看>>
Delphi中读取文本文件的方法(实例一)
查看>>
Linux常用命令
查看>>
Android开源代码解读の使用TelephonyManager获取移动网络信息
查看>>
想说一点东西。。。。
查看>>
css知多少(8)——float上篇
查看>>
NLB网路负载均衡管理器详解
查看>>
水平添加滚动条
查看>>
PHP中”单例模式“实例讲解
查看>>
VS2008查看dll导出函数
查看>>
VM EBS R12迁移,启动APTier . AutoConfig错误
查看>>
atitit.细节决定成败的适合情形与缺点
查看>>
iOS - Library 库
查看>>
MATLAB 读取DICOM格式文件
查看>>
spring事务管理(Transaction)
查看>>
django.contrib.auth登陆注销学习
查看>>
js执行本地exe文件的3种方法
查看>>
理解B树索引
查看>>