【问题标题】:onesignal with react-navigation and redux: i am not able to navigate to screen when notification is opened带有 react-navigation 和 redux 的 onesignal:打开通知时我无法导航到屏幕
【发布时间】:2018-12-23 11:55:15
【问题描述】:

问题:
打开 onesignal 通知时,我需要导航到屏幕。

情况:
我无法从我的 App 组件导航,因为尚未定义导航器。
我无法从我的 RootContainer 组件导航,因为尚未定义导航器。

我考虑过调度操作而不是导航,但还是一样:
我无法从我的 App 组件调度操作,因为尚未定义商店。
我无法从我的 RootContainer 组件调度操作,因为尚未定义导航。

这是 App.js:

... import

const persistConfig = {
    key: 'root',
    version: 1,
    storage,
    blacklist: ['navigation']
};

const persistedReducer = persistReducer(persistConfig, reducer);

const store = createStore(persistedReducer, {
    is_logged_in: false,
    login_type: null,
    access_token: null
},
    applyMiddleware(logger));

const persistor = persistStore(store);
class App extends Component {

    constructor(props) {
        super(props);

        OneSignal.init("...");

        this.onOpened = this.onOpened.bind(this);

        OneSignal.addEventListener('received', this.onReceived);
        OneSignal.addEventListener('opened', this.onOpened);
        OneSignal.addEventListener('ids', this.onIds);

        this.state = {
            notification_offer_clicked: null
        };
    }

    componentWillUnmount() {
        OneSignal.removeEventListener('received', this.onReceived);
        OneSignal.removeEventListener('opened', this.onOpened);
        OneSignal.removeEventListener('ids', this.onIds);
    }

    onOpened(openResult) {
        this.setState({
            notification_offer_clicked: openResult.notification.payload.additionalData.offer
        });
    }

    render () {
        return (
            <Provider store={store}>
                <PersistGate loading={null} persistor={persistor}>
                    <RootContainer notification_offer_clicked={this.state.notification_offer_clicked} />
                </PersistGate>
            </Provider>
        )
    }
}

export default DebugConfig.useReactotron
  ? console.tron.overlay(App)
  : App

如您所见,我尝试将 notification_offer_clicked 属性传递给 RootContainer 以传播事件。
正确传递了道具,但我不知道如何从那里继续。

这是 Container.js:

... import

class RootContainer extends Component {
    shouldComponentUpdate(nextProps, nextState) {
        //if (nextProps.notification_offer_clicked) {
        //    this.props.navigation.navigate('Offer', { 'offer' : nextProps.notification_offer_clicked });
        //}
        return true;
    }

    render() {
        return (
            <AppNavigator />
        );
    }
}

const mapStateToProps = (state) => {
    return {
        is_logged_in: state.is_logged_in,
    };
};

// wraps dispatch to create nicer functions to call within our component
const mapDispatchToProps = (dispatch) => ({
    startup: () => dispatch(StartupActions.startup())
});

export default connect(mapStateToProps, mapDispatchToProps)(RootContainer)

AppNavigator 是一个StackNavigator 变量,所以我不知道如何(如果可能的话)将道具传递给它。

问题是如果我尝试去注释

this.props.navigation.navigate...

行我得到错误原因 navigation 尚未在 RootContainer 中定义。

我的问题是:当我打开 onesignal 通知时,如何导航到屏幕(或简单地发送 redux 操作)?

【问题讨论】:

    标签: javascript react-native react-redux react-navigation onesignal


    【解决方案1】:

    为什么不在主屏幕中初始化事件侦听器? 假设您有这种导航架构,

    SCREEN1: 
    - SUBSCREEN1,
    - SUBSCREEN2,
    

    现在,您可以将事件侦听器添加到 Screen1 组件。 为了实现动态方法,您可以从一个信号发送路线名称, 例如。一个信号数据包是..

        notifications: {
          payload: {
            additionalData: {
            routeName: 'SUBSCREEN1',
            params: {
              id: 12
            }
           }
         }
       }
    

    然后您可以有效地从父屏幕导航到嵌套屏幕,因为您也获得了 routeName 和道具... 然后你可以在你的 onOpened 监听器上定义一个简单的函数,比如说onOpened...

    onOpened = (data) => {
    // some validation if there is a data or not,,, if there is
    this.props.navigation.navigate(data.notification.payload.additionalData.routeName,data.notification.payload.addtionalData.params);
    }
    

    在这里你传递了一个 routeName 和 props,它可以导航到具有所需 props 的任何屏幕,

    注意:您始终需要在导航之前验证数据,以减少错误和崩溃的数量。而且你的根组件上不需要事件监听器。

    您不需要这样做,因为当您单击通知时,它会等到收到事件侦听器,一旦收到事件侦听器,它就会执行最后一个通知,我知道这是 onesignal 的奇怪行为.

    【讨论】:

    • 我使用了onesignal文档中写的code代码。这就是为什么我把它放在 App 文件中。
    • 你不需要那个......我会用原因更新我的答案
    • 我在生产应用程序中使用了这种方法,它完美无缺
    • 听者的事我没看懂
    • 好的...所以基本上如果您有两个屏幕,屏幕 1,屏幕 2,当前您位于屏幕 1,但屏幕 2 是事件侦听器在您收到通知时初始化的位置,并且假设您单击它,什么都不会发生..当您导航到 screen2 一段时间后,onOpened 函数将触发,因此它等待事件侦听器。这就是原因,您不需要根组件中的侦听器,这样很难解释。如果有帮助,请告诉我。
    猜你喜欢
    • 2019-12-01
    • 1970-01-01
    • 2019-01-29
    • 2022-11-19
    • 1970-01-01
    • 2020-10-10
    • 1970-01-01
    • 1970-01-01
    • 2018-04-08
    相关资源
    最近更新 更多