RN OneSignal _open 事件
Posted
技术标签:
【中文标题】RN OneSignal _open 事件【英文标题】:RN OneSignal _open Event 【发布时间】:2021-07-14 13:38:25 【问题描述】:OneSignal on notification open 事件在主屏幕启动后触发,然后导航到所需的屏幕。我想检测应用程序是否在主屏幕呈现之前按通知启动,以便我可以直接导航到第二个屏幕并避免不必要地调用 api。
“react-native-onesignal”:“^3.9.3” “反应导航”:“^4.0.0”
代码
const _opened = openResult =>
const additionalData, body = openResult.notification.payload;
// how to navigate or set the initial screen depending on the payload
useEffect(() =>
onesignal.init();
onesignal.addEventListener('received', _received);
onesignal.addEventListener('opened', _opened);
SplashScreen.hide();
return () =>
// unsubscriber
onesignal.removeEventListener('received', _received);
onesignal.removeEventListener('opened', _opened);
, []);
调试
【问题讨论】:
【参考方案1】:您的问题是如何导航或设置初始屏幕取决于打开的通知负载?
1) - 根据打开的通知负载设置initial screen
。
根据class LifecycleuseEffect
在组件输出被渲染后运行,所以useEffect
中的监听器直到组件数量才被监听,这也是在useEffect
之前登录主屏幕显示的原因,看到这个解释。
//this the problem (NavigationContainer called before useEffect).
function App()
useEffect(() => ); //called second.
return <NavigationContainer>; //called first.
//this the solution (useEffect called Before NavigationContainer).
function App()
const [ready, setReady] = useState(false);
//called second.
useEffect(() =>
//listen here
setReady(true);
SplashScreen.hide();
);
//called first
//no function or apis run before useEffect here it just view.
if(!ready) return <></>;// or <LoadingView/>
//called third.
return <NavigationContainer>;
你的代码可能是这样的。
function App()
const [ready, setReady] = useState(false);
const openedNotificationRef = useRef(null);
const _opened = openResult =>
openedNotificationRef.current = openResult.notification.payload;
const getInitialRouteName = () =>
if (openedNotificationRef.current)
return "second"; //or what you want depending on the notification.
return "home";
useEffect(() =>
onesignal.addEventListener('opened', _opened);
//setTimeout(fn, 0) mean function cannot run until the stack on the main thread is empty.
//this ensure _opened is executed if app is opened from notification
setTimeout(() =>
setReady(true);
, 0)
);
if(!ready) return <LoadingView/>
return (
<NavigationContainer initialRouteName=getInitialRouteName()>
</NavigationContainer>
);
2) - navigate
取决于打开的通知负载。
首先你需要知道
需要渲染导航器才能处理操作如果您 尝试在不呈现导航器的情况下或在导航器之前导航 完成安装,如果不处理,它将抛出并崩溃您的应用程序。所以 您需要添加额外的检查来决定要做什么,直到您 应用挂载。
阅读docs
function App()
const navigationRef = React.useRef(null);
const openedNotificationRef = useRef(null);
const _opened = openResult =>
openedNotificationRef.current = openResult.notification.payload;
//remove loading screen and start with what you want.
const routes = [
name : 'home', //recommended add this to handle navigation go back
name : 'orders', //recommended add this to handle navigation go back
name : 'order', params : id : payload.id,
]
navigationRef.current.dispatch(
CommonActions.reset(
routes : routes,
index: routes.length - 1,
)
)
useEffect(() =>
//don't subscribe to `opened` here
//unsubscribe
return () =>
onesignal.removeEventListener('opened', _opened);
, []);
//subscribe to `opened` after navigation is ready to can use navigate
const onReady = () =>
onesignal.addEventListener('opened', _opened);
//setTimeout(fn, 0) mean function cannot run until the stack on the main thread is empty.
//this ensure _opened is executed if app is opened from notification
setTimeout(() =>
if (!openedNotificationRef.current)
//remove loading screen and start with home
navigationRef.current.dispatch(
CommonActions.reset(
routes : [name : 'home'],
index: 0,
)
)
, 0)
;
return (
<NavigationContainer
ref=navigationRef
onReady=onReady
initialRouteName="justLoadingScreen">
</NavigationContainer>
);
setTimeout、CommonActions 的引用。
【讨论】:
以上是关于RN OneSignal _open 事件的主要内容,如果未能解决你的问题,请参考以下文章
Ionic3 OneSignal 如何检查应用程序是不是由于通知打开事件而启动