带有反应导航和 redux 的信号:打开通知时我无法导航到屏幕
onesignal with react-navigation and redux: i am not able to navigate to screen when notification is opened
问题:
打开单信号通知时,我需要导航到屏幕。
情况:
我无法从我的 App 组件导航,因为导航器尚未定义。
我无法从我的 RootContainer 组件导航,因为导航器尚未定义。
我想过dispatch action而不是navigate,但是一样:
我无法从我的 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
prop 传递给 RootContainer 以传播事件。
prop 正确通过,但我不知道如何继续。
这是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 中定义。
我的问题是:当我打开一个信号通知时,如何导航到屏幕(或简单地发送 redux 操作)?
为什么不在主屏幕中初始化事件侦听器?
假设您有这种导航架构,
SCREEN1:
- SUBSCREEN1,
- SUBSCREEN2,
现在,您可以将事件侦听器添加到 Screen1 组件中。
并采用动态方法,您可以从一个信号发送路线名称,
例如。一个信号数据包是..
notifications: {
payload: {
additionalData: {
routeName: 'SUBSCREEN1',
params: {
id: 12
}
}
}
}
然后你可以有效地从父级导航到嵌套屏幕,因为你也得到了 routeName 和 props ...
然后你可以在你的 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
.
问题:
打开单信号通知时,我需要导航到屏幕。
情况:
我无法从我的 App 组件导航,因为导航器尚未定义。
我无法从我的 RootContainer 组件导航,因为导航器尚未定义。
我想过dispatch action而不是navigate,但是一样:
我无法从我的 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
prop 传递给 RootContainer 以传播事件。
prop 正确通过,但我不知道如何继续。
这是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 中定义。
我的问题是:当我打开一个信号通知时,如何导航到屏幕(或简单地发送 redux 操作)?
为什么不在主屏幕中初始化事件侦听器? 假设您有这种导航架构,
SCREEN1:
- SUBSCREEN1,
- SUBSCREEN2,
现在,您可以将事件侦听器添加到 Screen1 组件中。 并采用动态方法,您可以从一个信号发送路线名称, 例如。一个信号数据包是..
notifications: {
payload: {
additionalData: {
routeName: 'SUBSCREEN1',
params: {
id: 12
}
}
}
}
然后你可以有效地从父级导航到嵌套屏幕,因为你也得到了 routeName 和 props ...
然后你可以在你的 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
.