Хорошо, поэтому я не уверен, что это лучший способ справиться с этим, но я нашел способ заставить мои уведомления работать.
(1) Я создал действие с именем registerAppLoaded
и переменную состояния appLoaded
, которую отправляю, как только мой компонент AppLoading
завершит свои функции startAsync
.
(2) Когда приходит уведомление, сначала я проверяю, истинно ли appLoaded
. Если это так, я перехожу к пункту назначения, отправленному вместе с уведомлением. Если нет, я помещаю уведомление в магазин и продолжаю запускать приложение.
(3) в функции AppLoading
onFinish
, я проверяю, есть ли уведомление. Если это так, и он помечен new
, я беру его и использую параметры для навигации. Затем я отправляю действие, которое устанавливает navigation.new = false
Кажется, работает именно так, как мне нужно!
Вот мой код, если кто-то еще имеет дело с этой проблемой:
App.tsx:
export default class App extends React.Component {
componentDidMount() {
Notifications.addListener((notification) => {
if (notification.origin === "received") {
return;
} else {
const appLoaded = store.getState().general.appLoaded
if (appLoaded) {
NavigationService.navigate(notification.data.navigate, {id:notification.data.id , shouldRefresh: true})
} else {
// save notification as new
store.dispatch(addNotification(notification, true));
}
};
})
}
render() {
return (
<Provider store={store}>
<PersistGate loading={null} persistor={persistor}>
<View style={styles.container}>
{Platform.OS === "ios" && <StatusBar barStyle="default" />}
<ErrorBoundary backup={<AppError />}>
<AppNavigator />
</ErrorBoundary>
</View>
</PersistGate>
</Provider>
);
}
}
AppLoading.tsx:
class AppLoadingScreen extends React.Component {
_loadResourcesAsync = async() => {
await this.props.fetchUserOnboarding(this.props.userId);
if (this.props.userDevice && this.props.userDevice.id) {
this.props.registerUserDevice(this.props.userId, this.props.userDevice.id)
}
// register that the app has finished loading in the store; this will be used to determine if a notification's deep
// link should be immediatedly navigated to or if the navigation even shuold be deferred until after the app
// finishes loading
await this.props.registerAppLoaded()
};
_handleFinishLoading = async () => {
// if a notification triggers the event listener but the app is not yet fully loaded, the deep link will be
// navigated to here instead of directly from the listener
const notification = this.props.userNotifications && this.props.userNotifications[0]
if (notification && notification.new && notification.origin != 'recieved') {
this.props.addNotification(notification, false) // set notification.new = false
this.props.navigation.navigate(notification.data.navigate, {id: notification.data.id, shouldRefresh: true})
} else if (this.props.showGoalsPrompt) {
this.props.navigation.navigate("Goal");
} else {
this.props.navigation.navigate("HomeFeed");
}
};
render() {
return (
<AppLoading
startAsync={this._loadResourcesAsync}
onFinish={this._handleFinishLoading}
/>
);
}
}
actions.tsx:
export const registerAppLoaded = () => {
return dispatch => {
dispatch({
type: types.REGISTER_APP_LOADED,
payload: true
});
};
}
export const addNotification = (notification, isNew=false) => {
return dispatch => {
notification.new = isNew // indicate whether this is a new notification or if it has been seen
dispatch({
type:types.ADD_USER_NOTIFICATION,
payload: notification,
})
};
}