oneSignal с реакции-навигацией и избыточностью: я не могу перейти к экрану при открытии уведомления - PullRequest
0 голосов
/ 23 декабря 2018

Проблема:
Мне нужно перейти на экран при открытии уведомления о сигнале.

Ситуация:
Не могуперейти из моего компонента приложения, потому что навигатор еще не определен.
Я не могу перейти из моего компонента RootContainer, потому что навигатор еще не определен.

Я думал о диспетчерском действии вместо навигации, но то же самое:
Я не могу отправить действие из моего компонента приложения, потому что хранилище еще не определено.
Я не могу отправить действие из моего 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 prop в 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.

У меня такой вопрос: как я могу перейти к экрану (или просто отправить избыточное действие) при открытии уведомления об одном сигнале?

1 Ответ

0 голосов
/ 23 декабря 2018

Почему вы не инициализируете прослушиватели событий на главном экране?Допустим, у вас есть эта навигационная архитектура,

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 и реквизиты таким образом, что он может перейти к любому экрану с необходимыми реквизитами,

ПРИМЕЧАНИЕ: выВсегда нужно проверять данные перед навигацией, чтобы уменьшить количество ошибок и сбоев.И вам не нужны прослушиватели событий в вашем корневом компоненте.

Это вам не нужно, потому что, когда вы нажимаете на уведомление, он ждет, пока не получит прослушиватель событий, и как только он получит прослушиватель событий., он выполняет последнее уведомление, которое я знаю, его странное поведение с onesignal.

...