我想我的应用程序的状态确实有一些问题。我已经知道this.setState({ ... })
是一个异步工作的函数。。所以,我认为这与我的问题有关。
我的问题是,当我通过OneSignal发送推送通知时,我想向用户显示一个弹出对话框。iOS和Android都会收到此推送通知。即使应用程序在背景,前景或被杀,甚至没有在背景中运行。对于弹出对话框,我使用这个包:反应本地弹出对话框
只有当我发送带有推送通知的特定键/值对时,此弹出窗口才可见。这些密钥是:
showPopup
:true
-当为true时显示弹出窗口。如果未设置或不等于true,则不会显示openLink
:mydomain.de
-添加一个带有弹出窗口链接的按钮buttonText
:Open in Browser
-将按钮文本设置为链接
注意,只有在设置了
openLink
和buttonText
键的情况下,才会将额外的URL按钮添加到弹出窗口中。其中没有一个或只设置了一个键,它不会显示此按钮。
但是,弹出对话框仅在某些情况下显示。我将在下面为您列出它们:
- 情况1:应用程序已打开。在这种情况下,弹出窗口会显示在iOS和Android上。这由
onReceived
功能 - 案例2:应用程序完全关闭(从屏幕上滑下/关闭)。在这种情况下,弹出窗口显示在Android上设备,但不在iOS设备上!这由
onOpened
函数处理 - 案例3:该应用程序已打开,目前正在后台运行。在这种情况下,弹出窗口会显示在iOS上设备,但不在Android设备上。这也由
onOpened
函数处理
所以,由于我没有收到错误消息或其他什么,我想我的猜测是正确的,这个问题是由于异步CCD_ 13功能。
我现在的问题是,在渲染getPopup(...)
方法之前,如何确保始终设置notification
和visible
的状态。。我已经在考虑实现它,以便用参数调用getPopup(...)
函数。因此,我可以确定参数总是在调用该方法之前设置好的。然而,遗憾的是,这是不可能的。因为你在下面看到的类,SuperScreen
类,只是一个被一些子类扩展的类,用来捆绑我的代码,比如推送通知代码或我在每个子类中需要的一些函数。
此外,我已经尝试向我的SuperClass
状态添加一个变量,例如stateSet
,它在onReceived
或onOpened
的setState({ ... })
函数完成后设置,并用CCD_ 25函数的第一行中的CCD_。然而,这也是不可能的。原因是当我按下Ok
或链接按钮时,我的弹出窗口不再关闭。
如果你们对如何解决这个问题有任何想法,我真的很感激!这是我的代码:
export default class SuperScreen extends Component {
constructor(props) {
super(props);
this.state = {
pushNotification: null,
visible: false
};
OneSignal.init("00000000", {
kOSSettingsKeyAutoPrompt: true
});
OneSignal.inFocusDisplaying(0);
OneSignal.enableVibrate(true);
OneSignal.enableSound(true);
OneSignal.addEventListener("received", this.onReceived);
OneSignal.addEventListener("opened", this.onOpened);
OneSignal.addEventListener("ids", this.onIds);
}
componentWillUnmount() {
OneSignal.removeEventListener("received", this.onReceived);
OneSignal.removeEventListener("opened", this.onOpened);
OneSignal.removeEventListener("ids", this.onIds);
}
onReceived = notification => {
//App is opened!
console.log("Notification received: ", notification);
this.setState({
pushNotification: notification,
visible: true
});
if (notification.payload.notificationID != null) {
firebase.analytics().logEvent("Popup_Link_Button", {
notificationID: notification.payload.notificationID,
clicked: true
});
}
};
onOpened = openResult => {
//App either is closed or running in background
//Android: Closed: Showing Background: Not Showing
//iOS: Closed: Not Showing Background: Showing)
console.log("openResult: ", openResult);
this.setState({
pushNotification: openResult.notification,
visible: true
});
if (openResult.notification.payload.notificationID != null) {
firebase.analytics().logEvent("Popup_Link_Button", {
notificationID: openResult.notification.payload.notificationID,
clicked: true
});
}
};
onIds = device => {
console.log("Device info: ", device);
};
getPopup() {
if (
this.state.pushNotification != null &&
this.state.pushNotification.payload.additionalData != null &&
this.state.pushNotification.payload.additionalData.showPopup != null &&
this.state.pushNotification.payload.additionalData.showPopup == "true"
) {
var actionButtons = null;
if (
this.state.pushNotification.payload.additionalData.openLink != null &&
this.state.pushNotification.payload.additionalData.buttonText != null
) {
actionButtons = [
<DialogButton
text="Ok"
key={0}
onPress={() => {
this.setState({ visible: false });
firebase.analytics().logEvent("Popup_Link_Button", {
notificationID: this.state.pushNotification.payload
.notificationID,
opened: false
});
}}
/>
];
actionButtons.push(
<DialogButton
text={this.state.pushNotification.payload.additionalData.buttonText}
key={1}
onPress={() => {
this.openLink(
this.state.pushNotification.payload.additionalData.openLink
);
this.setState({ visible: false });
firebase.analytics().logEvent("Popup_Link_Button", {
notificationID: this.state.pushNotification.payload
.notificationID,
link: this.state.pushNotification.payload.additionalData
.openLink,
opened: true
});
}}
/>
);
} else {
actionButtons = [
<DialogButton
text="Ok"
key={0}
onPress={() => {
this.setState({ visible: false });
firebase.analytics().logEvent("Popup_Link_Button", {
popupID: this.state.pushNotification.payload.notificationID,
opened: false
});
}}
/>
];
}
return (
<Dialog
visible={this.state.visible}
dialogTitle={
<DialogTitle
title={
this.state.pushNotification == null
? ""
: this.state.pushNotification.payload.title
}
/>
}
dialogAnimation={
new SlideAnimation({
slideFrom: "bottom"
})
}
dialogStyle={{ marginLeft: 20, marginRight: 20 }}
actions={actionButtons}
>
<DialogContent>
<Text />
<Text>
{this.state.pushNotification == null
? ""
: this.state.pushNotification.payload.body}
</Text>
</DialogContent>
</Dialog>
);
}
}
您可以向setState添加回调,以确保代码在设置状态后运行:
this.setState().then({ //Do something here. })
异步使用async
、await
。
onReceived = async (notification) => {
//App is opened!
console.log("Notification received: ", notification);
await this.setState({ // It will wait until finish setState.
pushNotification: notification,
visible: true
});
if (notification.payload.notificationID != null) {
firebase.analytics().logEvent("Popup_Link_Button", {
notificationID: notification.payload.notificationID,
clicked: true
});
}
};
您可以在setState中使用回调!,我一个月前就从中吸取了教训,从那以后一直很有用。查看本文,您可以将函数作为回调传递;)
this.setState(
{ pushNotification: notification,
visible: true }, () => {this.getPopup()}) //this.getPopup it's the second parameter, a callback
查看文章,它很短,将有助于