jpush / jpush-react-native

JPush's officially supported React Native plugin (Android & iOS). 极光推送官方支持的 React Native 插件(Android & iOS)。
http://docs.jiguang.cn
MIT License
1.35k stars 336 forks source link

关于点击推送消息跳转到对应界面的问题 #321

Closed duanyachao closed 6 years ago

duanyachao commented 7 years ago

我在APP入口文件RootScene.JS里面,通过react-navigation设置了根路由,在componentDidMount()方面里面设置了监听点击推送消息后跳转界面的事件,运行测试:先退出APP再发送推送消息,按之前设置的路由走下去报错,提示navigation undefined,请教大神是什么问题,代码如下: `//import liraries import React, { Component } from 'react'; import { DeviceEventEmitter, NativeAppEventEmitter, View, Text, StyleSheet, BackHandler } from 'react-native'; import Icon from 'react-native-vector-icons/FontAwesome'; import SplashScene from './SplashScene'; import LoginScene from './scene/Mine/LoginScene'; import { StackNavigator, TabNavigator, TabBarBottom } from 'react-navigation'; import { theme, system, screen } from './common'; import { Network, toastShort } from '../src/utils'; import { TabBarItem, Header, Button } from './components'; import WarnScene from './scene/Warn/WarnScene'; import TaskScene from './scene/Task/TaskScene'; import ProductScene from './scene/Product/ProductScene'; import DeviceScene from './scene/Device/DeviceScene'; import EbusinessScene from './scene/Ebusiness/EbusinessScene'; import MineScene from './scene/Mine/MineScene'; import UserInfoScene from './scene/Mine/UserInfoScene' import MyprofitScene from './scene/Mine/MyprofitScene' import MsgScene from './scene/Mine/MsgScene' import ModifyPasswordScene from './scene/Mine/ModifyPasswordScene' import VideoScene from './scene/Video/VideoScene' import JPushModule from 'jpush-react-native'; const TabScene = TabNavigator({ Warn: { screen: WarnScene, navigationOptions: ({navigation}) => ({ header:

, tabBarLabel: '报警', tabBarIcon: ({ tintColor, focused }) => ( <Icon name={'warning'} size={theme.tabIconsize} style={{ color: tintColor }}> ) }) }, Task: { screen: TaskScene, navigationOptions: ({navigation}) => ({ header:
, tabBarLabel: '任务', tabBarIcon: ({ tintColor, focused }) => ( <Icon name={'tasks'} size={theme.tabIconsize} style={{ color: tintColor }}> ) }) }, Product: { screen: ProductScene, navigationOptions: ({navigation}) => ({ header:
, tabBarLabel: '生产', tabBarIcon: ({ tintColor, focused }) => ( <Icon name={'product-hunt'} size={theme.tabIconsize} style={{ color: tintColor }}> ) }) }, Device: { screen: DeviceScene, navigationOptions: ({navigation}) => ({ header:
, tabBarLabel: '设备', tabBarIcon: ({ tintColor, focused }) => ( <Icon name={'sliders'} size={theme.tabIconsize} style={{ color: tintColor }}> ) }) }, // Ebusiness: { // screen: EbusinessScene, // navigationOptions: ({navigation}) => ({ // header:
, // tabBarLabel: '农资', // tabBarIcon: ({ tintColor, focused }) => ( // <Icon name={'shopping-cart'} // size={theme.tabIconsize} // style={{ color: tintColor }}> // // ) // }) // }, Video: { screen: VideoScene, navigationOptions: ({navigation}) => ({ header:
, tabBarLabel: '监控', tabBarIcon: ({ tintColor, focused }) => ( <Icon name={'video-camera'} size={theme.tabIconsize} style={{ color: tintColor }}> ) }) }, Mine: { screen: MineScene, navigationOptions: ({navigation}) => ({ header: null, tabBarLabel: '我的', tabBarIcon: ({ tintColor, focused }) => ( <Icon name={'user'} size={theme.tabIconsize} style={{ color: tintColor }}> ) }) } }, { initialRouteName: 'Warn', backBehavior: "none", tabBarComponent: TabBarBottom, tabBarPosition: 'bottom', swipeEnabled: true, lazy: true, // order: ["Home", "Nearby", "Order", "Mine"], animationEnabled: true, tabBarOptions: { showIcon: true, activeTintColor: theme.theme, inactiveTintColor: '#979797', labelStyle: { fontSize: theme.tabFontSize, }, style: { backgroundColor: '#fff' }, }, } ); const StackOptions = ({navigation}) => { let {state, goBack} = navigation; const headerStyle = { height: 45, flexDirection: 'row', backgroundColor: '#fff', borderBottomWidth: screen.onePixel, borderBottomColor: '#ccc' }; const headerTitle = state.params.title; const headerTitleStyle = { color: '#a9a9a9', fontSize: 16 } const headerBackTitle = false; const headerLeft = <Icon.Button borderRadius={0} name="angle-left" backgroundColor="transparent" size={30} color='#ccc' iconStyle={{ marginLeft: 10 }} activeOpacity={.4} underlayColor={'#eee'} onPress={() => goBack()} style={{ marginBottom: 5 }}

</Icon.Button>; return { headerStyle, headerTitle, headerTitleStyle, headerBackTitle, headerLeft } }; const Navigator = StackNavigator({ Splash: { screen: SplashScene }, Login: { screen: LoginScene }, Tab: { screen: TabScene }, UserInfo: { screen: UserInfoScene, navigationOptions: ({navigation}) => StackOptions({ navigation }) }, ModifyPassword: { screen: ModifyPasswordScene, navigationOptions: ({navigation}) => StackOptions({ navigation }) }, Myprofit: { screen: MyprofitScene, navigationOptions: ({navigation}) => StackOptions({ navigation }) }, Msg: { screen: MsgScene, }

}, { mode: (system.isAndroid) ? 'card' : 'modal', } ); export default class RootScene extends Component { constructor(props) { super(props) this.state = {

    }
}
onBackAndroid = () => {
    let routes = this.refs.navigator.state.nav.routes;

    if (routes.length == 1) {
        if (this.lastBackPressed && this.lastBackPressed + 2000 >= Date.now()) {
            BackHandler.exitApp();
            return true;
        }
        this.lastBackPressed = Date.now();
        toastShort('再按一次退出应用');
        return true
    } else {
        return false
    }

}
componentDidMount() {
    if (system.isAndroid) {
        BackHandler.addEventListener('hardwareBackPress', this.onBackAndroid);
    }
    // 在收到点击事件之前调用此接口
    JPushModule.notifyJSDidLoad((resultCode) => {
        if (resultCode === 0) {
        }
    });
    this.loginListener = DeviceEventEmitter.addListener('loginSuccess', (msg) => {
        // console.info(msg)
        JPushModule.setAlias(msg, (map) => {
            if (map.errorCode === 0) {
                // console.log("set alias succeed");
            } else {
                // console.log("set alias failed, errorCode: " + map.errorCode);
            }
        });
    })
    JPushModule.getInfo((map) => {
        console.info(map)
    });
    JPushModule.addReceiveNotificationListener((message) => {
        // console.log(JSON.stringify(message));
        console.info(this.props.navigation)
        this.props.navigation.navigate("Msg")
    })

}
componentWillUnmount() {
    if (system.isAndroid) {
        BackHandler.removeEventListener('hardwareBackPress', this.onBackAndroid);
    }
    this.loginListener.remove();
    JPushModule.removeReceiveCustomMsgListener();
    JPushModule.removeReceiveNotificationListener();
}
render() {
    return (
        <Navigator ref='navigator'></Navigator>
    );
}

}

`

KenChoi1992 commented 7 years ago

你退出 app 再通过点击通知起来的时候,需要判断一下 navigation 有没有初始化

duanyachao commented 7 years ago

@KenChoi1992 你的意思是等navigation有值再进行跳转,我用延时执行跳转,不管延时多久,依然找不到 navigation 请问怎么判断有没有初始化

KenChoi1992 commented 7 years ago

@duanyachao 如果为 undefined 那就是没有初始化啊

duanyachao commented 7 years ago

@KenChoi1992 if(this.props.navigation){ this.props.navigation.navigate("Msg"); }难道是这样?

KenChoi1992 commented 7 years ago

@duanyachao

if (this.props.navigation === undefined) {
    // 启动主页面,初始化 navigation
    // 保存跳转事件,初始化完成后跳转
} else {
    // 跳转
}