当我的应用程序收到推送通知时,应使用通知数据中的routeName参数导航到适当的屏幕。
这一直有效,直到我按照react-navigation docs中所述的NavigationService模式抽象出导航,并在反应导航问题here中充实了。
我遇到的问题是from react-navigation:不变违反:如果有状态,应在构造函数中设置
为解决此问题,我尝试绕过addListener
调用。我已经尝试了App componentDidMount
,AppWithNavigation ref回调(这似乎是个坏主意)和NavigationService的setContent
方法。
我尝试了使用NavigationService的监听器的各种变体,这些变体直接在App中与NavigationActions.navigate
一起使用store.dispatch
。
我的理论是导航容器在变化,但是导航正常运行,除了关闭应用程序并发出通知时。我什至让它在打开应用程序的情况下工作,在这种情况下,它确实移至了右屏幕。
我在这里想念什么?
监听器如下:
Notifications.addListener(({data}: {data: NotificationType}) => {
const {routeName, params} = data;
NavigationService.navigate({
routeName,
params,
});
});
NavigationService.js:
import {StackActions, NavigationActions} from 'react-navigation';
import type {NavigationParams, NavigationRoute} from 'react-navigation';
import {LOGOUT} from '../redux/auth';
let _container; // eslint-disable-line
function setContainer(container: Object) {
_container = container;
}
function reset(routeName: NavigationRoute, params?: NavigationParams) {
_container.dispatch(
StackActions.reset({
index: 0,
actions: [
NavigationActions.navigate({
routeName,
params,
}),
],
}),
);
}
function navigate(routeName: string, params?: NavigationParams) {
_container.dispatch(
NavigationActions.navigate({
routeName,
params,
}),
);
}
function goBack(options) {
_container.dispatch(NavigationActions.back(options));
}
function getCurrentRoute(): NavigationRoute | null {
if (!_container || !_container.state.nav) {
return null;
}
return _container.state.nav.routes[_container.state.nav.index] || null;
}
export function logOut() {
_container.dispatch({type: LOGOUT});
reset('Welcome');
}
export default {
setContainer,
navigate,
reset,
goBack,
logOut,
};
Navigators.js的一部分
class AppWithNavigationState extends Component {
render() {
return (
<React.Fragment>
{/* Fix for white icons on white status bar bug on iOS */}
{!isAndroid && <StatusBar barStyle="dark-content" />}
<RootStack
persistenceKey="NavigationState-2"
ref={navigatorRef => NavigatorService.setContainer(navigatorRef)}
/>
</React.Fragment>
);
}
}
export default AppWithNavigationState;
答案 0 :(得分:0)
我遇到了同样的问题。我的设置与您的设置非常相似,问题是在应用程序导航器完成启动之前,我作为传奇人物进行了导航。检查您是否正在使用persistenceKey
,如果是,则先前的状态会被异步水化,这是我遇到问题的原因。
我在navigationReady
的主导航器中有一个回调componentDidMount
,但是我认为我必须将其移至实际屏幕上才能避免该问题。目前,在还原所有内容之后,我找不到合适的方法来订阅由容器分派的操作Navigation / INIT
。
答案 1 :(得分:0)
这是我最终得到的解决方案。这并不理想,因此希望尽快升级到反应导航3。我在加载时使用renderLoadingExperimental
渲染SplashScreen。加载完成后无法收到通知,因此我在SplashScreen中添加了onUnmount
,并在那里进行注册。
class AppWithNavigationState extends Component {
render() {
return (
<React.Fragment>
<RootStack
persistenceKey="NavigationState-2"
ref={navigatorRef => NavigationService.setContainer(navigatorRef)}
renderLoadingExperimental={() => (
<SplashScreen
source="RootStack"
onUnmount={() => {
Notifications.addListener(({data}) => {
NavigationService.navigate(data.routeName, data.params);
if (Platform.OS === 'android')
Notifications.dismissAllNotificationsAsync();
});
}}
/>
)}
/>
</React.Fragment>
);
}
}
export default AppWithNavigationState;