I am developping an react-native mobile application which will be mainly used in android platform. I recently needed to upgrade react native version for react-native-firebase. React-native version was 0.57.2
. I upgraded onto 0.59.6
using rn-diff-purge. While doing so, I needed to update react-navigation version from 2.17.0
to 3.8.1
(but type version is @types/react-navigation": "^2.0.23"
as you can see, I don't know if that makes a difference)
After upgrading, only headache was again react-navigation. I solved some issues. But after all, when I enable debug-js remotely, navigation transitions become extremely slow. Especially this.props.navigation.goBack();
calls. I tried giving name of the component like this.props.navigation.navigate("SomeRouter");
, but issue is about components' being already mounted, I guess.
Why is this the case? What can be the reason of slowing? How can I debug this? By the way, when debug js remotely is disabled, there is no problem, When debug js remotely enabled, transitions become a disaster!
Here is an example component:
import React, { Component } from "react";
import { BackHandler, Dimensions, StyleSheet, Text, View } from "react-native";
import Image from "react-native-scalable-image";
import { NavigationScreenProp, NavigationState } from "react-navigation";
import { connect } from "react-redux";
import MenuButton from "../components/MenuButton";
import * as types from "../store/types";
interface IProp {
navigation: NavigationScreenProp<NavigationState>;
}
interface ReduxProps {
currentUser?: types.User;
currentCompany?: types.Company;
currentStore?: types.Store;
}
class Menu extends Component<IProp & ReduxProps> {
state = {
UserPermissions: this.props.currentUser.permissions,
CompanyNo: this.props.currentCompany.SIRKETNO,
StoreNo: this.props.currentStore.BIRIMNO,
buttonCount: -1 as number,
buttonNames: [] as string[]
};
static navigationOptions = {
title: "OliMobile",
headerStyle: { marginTop: 0, backgroundColor: "#fff" },
headerLeft: null,
gesturesEnabled: false
};
componentDidMount() {
BackHandler.addEventListener("hardwareBackPress", this.handleBackButton);
}
componentWillUnmount() {
BackHandler.removeEventListener("hardwareBackPress", this.handleBackButton);
}
handleBackButton = () => {
this.props.navigation.goBack();
return true;
};
render() {
//console.log(this.renderButtonViews())
return (
<View style={styles.container}>
<View style={{ justifyContent: "flex-start", marginTop: -50 }}>
<Image
width={Dimensions.get("window").width} // height will be calculated automatically
source={require("../../img/OliMobile_logo.jpg")}
/>
{this.renderButtonViews()}
</View>
<View style={{ justifyContent: "flex-end" }}>
<Text
style={{
backgroundColor: "rgb(5, 128, 198)",
color: "white",
fontSize: 15
}}
>
Sicil No: {this.props.currentUser.sicilNo} Lokasyon No:{" "}
{this.props.currentStore.BIRIMNO}
</Text>
</View>
</View>
);
}
}
const mapStateToProps = (state: types.GlobalState) => ({
currentUser: state.User,
currentCompany: state.CurrentCompany,
currentStore: state.CurrentStore
});
export default connect<{}, {}, ReduxProps>(mapStateToProps)(Menu);
Here is the App.tsx:
/**
* OliMobile Source Code
*
*
* @author Hayri Durmaz
* @author Arda Tümay
*/
import React, { Component } from "react";
import { PermissionsAndroid, Platform, StyleSheet, View } from "react-native";
import Firebase from "react-native-firebase";
import { createAppContainer, createStackNavigator } from "react-navigation";
import { Provider } from "react-redux";
import { PersistGate } from "redux-persist/integration/react";
import AKTIVASYON from "./screens/Aktivasyon";
import ChooseStore from "./screens/ChooseStore";
import FIRMAIRSLOKSELECTION from "./screens/firmaIrsaliyeleri/FIRMAIRSLOKSELECTION";
import FirmaIrsMalKabul from "./screens/firmaIrsaliyeleri/FirmaIrsMalKabul";
import FirmaIrsSiparisSelection from "./screens/firmaIrsaliyeleri/FirmaIrsSiparisSelection";
import HareketTipiSelection from "./screens/firmaIrsaliyeleri/HareketTipiSelection";
import IRSLOKSC from "./screens/irsaliyeLokasyon/cıkıs/IRSLOKSC";
import LOKASYONSELECTION from "./screens/irsaliyeLokasyon/cıkıs/LOKASYONSELECTION";
import SEVK from "./screens/irsaliyeLokasyon/cıkıs/SEVK";
import IRSLOKSG from "./screens/irsaliyeLokasyon/giris/IRSLOKSG";
import LOKASYONSELECTIONG from "./screens/irsaliyeLokasyon/giris/LOKASYONSELECTIONG";
import MALKABUL from "./screens/irsaliyeLokasyon/giris/MALKABUL";
import Login from "./screens/Login";
import Menu from "./screens/Menu";
import NOTIMPLEMENTED from "./screens/NOTIMPLEMENTED";
import SAYIM from "./screens/sayim/SAYIM";
import SAYIMKAYDET from "./screens/sayim/SAYIMKAYDET";
import SAYIMLOCATIONSELECTION from "./screens/sayim/SAYIMLOCATIONSELECTION";
import NORMALSIPARIS from "./screens/siparis/normalSiparis/NORMALSIPARIS";
import NSDESTINATIONSELECTION from "./screens/siparis/normalSiparis/NSDESTINATIONSELECTION";
import URUNSELECTION, {
Spinner
} from "./screens/siparis/normalSiparis/URUNSELECTION";
import SABLONSIPARIS from "./screens/siparis/sablonSiparis/SABLONSIPARIS";
import SABLONSIPARISDETAY from "./screens/siparis/sablonSiparis/SABLONSIPARISDETAY";
import URETIMKATEGORISELECTION from "./screens/uretim/siparisliUretim/UretimKategoriSelection";
import URETIMKAYDET from "./screens/uretim/siparisliUretim/UretimKaydet";
import UretimUrunSelection from "./screens/uretim/siparisliUretim/UretimUrunSelection";
import SIPSIZURETIMKATEGORISELECTION from "./screens/uretim/siparissizUretim/SIPSIZURETIMKATEGORISELECTION";
import { persistor, store } from "./store";
type Props = {};
const IMEI = require("react-native-imei");
export async function requestLocationPermission() {
try {
const granted = await PermissionsAndroid.request(
PermissionsAndroid.PERMISSIONS.READ_PHONE_STATE
);
if (granted === PermissionsAndroid.RESULTS.GRANTED) {
console.log("You can use the location");
alert("You can use the location");
} else {
console.log("location permission denied");
alert("Location permission denied");
}
} catch (err) {
console.warn(err);
}
}
export default class App extends Component<Props> {
notificationDisplayedListener: any;
notificationListener: any;
unsubscribeFromNotificationListener: any;
async getPermissions() {
return new Promise(async (resolve, reject) => {
const permissions = await PermissionsAndroid.request(
PermissionsAndroid.PERMISSIONS.READ_PHONE_STATE
);
if (permissions === PermissionsAndroid.RESULTS.GRANTED) resolve(true);
else reject(false);
});
}
componentWillUnmount = () => {
this.unsubscribeFromNotificationListener();
};
componentDidMount() {}
async componentWillMount() {
Firebase.messaging().subscribeToTopic("pushNotificationsGeneral");
const channel = new Firebase.notifications.Android.Channel(
"channelId",
"Channel Name",
Firebase.notifications.Android.Importance.Max
).setDescription("A natural description of the channel");
Firebase.notifications().android.createChannel(channel);
// the listener returns a function you can use to unsubscribe
this.unsubscribeFromNotificationListener = Firebase.notifications().onNotification(
notification => {
if (Platform.OS === "android") {
const localNotification = new Firebase.notifications.Notification()
.setNotificationId(notification.notificationId)
.setTitle(notification.title)
.setSubtitle(notification.subtitle)
.setBody(notification.body)
.setData(notification.data)
.android.setChannelId("channelId") // e.g. the id you chose above
.android.setSmallIcon("ic_stat_olimobile") // create this icon in Android Studio
.android.setColor("#449DEF") // you can set a color here
.android.setPriority(Firebase.notifications.Android.Priority.High);
Firebase.notifications()
.displayNotification(localNotification)
.catch(err => console.error(err));
} else if (Platform.OS === "ios") {
const localNotification = new Firebase.notifications.Notification()
.setNotificationId(notification.notificationId)
.setTitle(notification.title)
.setSubtitle(notification.subtitle)
.setBody(notification.body)
.setData(notification.data)
.ios.setBadge(notification.ios.badge);
Firebase.notifications()
.displayNotification(localNotification)
.catch(err => console.error(err));
}
}
);
await this.getPermissions().then(sa => {
console.log(sa);
});
}
render() {
return (
<Provider store={store}>
<PersistGate loading={<Spinner size="large" />} persistor={persistor}>
<View style={{ flex: 1, backgroundColor: "gray" }}>
<Application />
</View>
</PersistGate>
</Provider>
);
}
}
const RootStack = createStackNavigator(
{
LoginRouter: Login,
ChooseStoreRouter: ChooseStore,
MenuRouter: Menu,
SABLONSIPARISRouter: SABLONSIPARIS,
SABLONSIPARISDETAYRouter: SABLONSIPARISDETAY,
NORMALSIPARISRouter: NORMALSIPARIS,
NSDESTINATIONSELECTIONRouter: NSDESTINATIONSELECTION,
URUNSELECTIONRouter: URUNSELECTION,
IRSLOKSCRouter: IRSLOKSC,
LOKASYONSELECTIONRouter: LOKASYONSELECTION,
SEVKRouter: SEVK,
IRSLOKSRouter: IRSLOKSG,
LOKASYONSELECTIONGRouter: LOKASYONSELECTIONG,
MALKABULRouter: MALKABUL,
SAYIMRouter: SAYIM,
SAYIMLOCATIONSELECTIONRouter: SAYIMLOCATIONSELECTION,
SAYIMKAYDETRouter: SAYIMKAYDET,
AKTIVASYONRouter: AKTIVASYON,
URETIMKATEGORISELECTIONRouter: URETIMKATEGORISELECTION,
URUNKONTROLRouter: NOTIMPLEMENTED,
IRSFIRMARouter: NOTIMPLEMENTED,
ETIKETLEMERouter: NOTIMPLEMENTED,
URETIMURUNSELECTIONRouter: UretimUrunSelection,
URETIMKAYDETRouter: URETIMKAYDET,
HareketTipiSelectionRouter: HareketTipiSelection,
FIRMAIRSLOKSELECTIONRouter: FIRMAIRSLOKSELECTION,
FirmaIrsSiparisSelectionRouter: FirmaIrsSiparisSelection,
FirmaIrsMalKabulRouter: FirmaIrsMalKabul,
SIPSIZURETIMKATEGORISELECTIONRouter: SIPSIZURETIMKATEGORISELECTION
},
{
// headerMode: "none",
initialRouteName: "LoginRouter",
initialRouteParams: { showAlert: true },
cardStyle: {
backgroundColor: "rgb(233, 233, 239)",
opacity: 1
}
// transitionConfig: () => ({
// transitionSpec: {
// duration: 0,
// timing: Animated.timing,
// easing: Easing.step0
// },
// swipeEnabled: false,
// animationEnabled: false
// })
}
);
// const MainNavigator = createStackNavigator(RootStack);
const Application = createAppContainer(RootStack);
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: "center",
alignItems: "center",
backgroundColor: "#F5FCFF"
},
welcome: {
fontSize: 20,
textAlign: "center",
margin: 10
},
instructions: {
textAlign: "center",
color: "#333333",
marginBottom: 5
}
});
Here is the old package.json:
{
"name": "Olimobile",
"version": "0.0.1",
"private": true,
"scripts": {
"start": "node node_modules/react-native/local-cli/cli.js start",
"test": "jest"
},
"dependencies": {
"@types/react-navigation": "^2.0.23",
"react": "16.5.0",
"react-native": "0.57.2",
"react-native-date-picker": "^2.2.1",
"react-native-dropdown-menu": "^2.0.0",
"react-native-easy-grid": "^0.2.0",
"react-native-elements": "^1.0.0",
"react-native-image-slider-show": "^1.0.3",
"react-native-imei": "^0.1.2",
"react-native-keyboard-aware-scroll-view": "^0.8.0",
"react-native-keyboard-spacer": "^0.4.1",
"react-native-material-dropdown": "^0.11.1",
"react-native-modal-dropdown": "^0.6.2",
"react-native-scalable-image": "^0.4.0",
"react-native-simple-dialogs": "^1.0.0",
"react-native-vector-icons": "^6.2.0",
"react-navigation": "^2.17.0",
"react-redux": "^6.0.0",
"react-xml-parser": "^1.0.8",
"redux": "^4.0.1",
"redux-persist": "^5.10.0"
},
"devDependencies": {
"@types/jest": "^23.3.3",
"@types/react": "^16.4.14",
"@types/react-native": "^0.57.1",
"@types/react-test-renderer": "^16.0.3",
"babel-jest": "23.6.0",
"jest": "23.6.0",
"metro-react-native-babel-preset": "0.47.1",
"react-native-typescript-transformer": "^1.2.10",
"react-test-renderer": "16.5.0",
"ts-jest": "^23.10.3",
"typescript": "^3.1.1"
},
"jest": {
"preset": "react-native",
"moduleFileExtensions": [
"ts",
"tsx",
"js"
],
"transform": {
"^.+\\.(js)$": "<rootDir>/node_modules/babel-jest",
"\\.(ts|tsx)$": "<rootDir>/node_modules/ts-jest/preprocessor.js"
},
"testRegex": "(/__tests__/.*|\\.(test|spec))\\.(ts|tsx|js)$",
"testPathIgnorePatterns": [
"\\.snap$",
"<rootDir>/node_modules/"
],
"cacheDirectory": ".jest/cache"
}
}
Here is my new package.json:
{
"name": "olimobile",
"version": "0.0.1",
"private": true,
"scripts": {
"start": "node node_modules/react-native/local-cli/cli.js start",
"test": "jest",
"lint": "tslint --project tsconfig.json"
},
"dependencies": {
"@types/react-navigation": "^2.0.23",
"react": "16.8.6",
"react-native": "^0.59.6",
"react-native-date-picker": "^2.3.0",
"react-native-dropdown-menu": "^2.0.0",
"react-native-easy-grid": "^0.2.0",
"react-native-elements": "^1.0.0",
"react-native-firebase": "^5.3.1",
"react-native-gesture-handler": "^1.1.0",
"react-native-image-slider-show": "^1.0.3",
"react-native-imei": "^0.1.2",
"react-native-keyboard-aware-scroll-view": "^0.8.0",
"react-native-keyboard-spacer": "^0.4.1",
"react-native-material-dropdown": "^0.11.1",
"react-native-modal-dropdown": "^0.6.2",
"react-native-scalable-image": "^0.4.0",
"react-native-simple-dialogs": "^1.0.0",
"react-native-vector-icons": "^6.2.0",
"react-navigation": "^3.8.1",
"react-redux": "^6.0.0",
"react-xml-parser": "^1.0.8",
"redux": "^4.0.1",
"redux-persist": "^5.10.0"
},
"devDependencies": {
"@babel/core": "^7.4.3",
"@babel/runtime": "^7.4.3",
"@types/jest": "^23.3.3",
"@types/node": "^11.13.6",
"@types/react": "^16.4.14",
"@types/react-native": "^0.57.1",
"@types/react-native-datepicker": "^1.7.0",
"@types/react-test-renderer": "^16.0.3",
"babel-jest": "^24.7.1",
"jest": "^24.7.1",
"metro-react-native-babel-preset": "^0.53.1",
"react-native-typescript-transformer": "^1.2.10",
"react-test-renderer": "16.8.3",
"ts-jest": "^23.10.3",
"tslint": "^5.16.0",
"typescript": "^3.1.1"
},
"jest": {
"preset": "react-native",
"moduleFileExtensions": [
"ts",
"tsx",
"js"
],
"transform": {
"^.+\\.(js)$": "<rootDir>/node_modules/babel-jest",
"\\.(ts|tsx)$": "<rootDir>/node_modules/ts-jest/preprocessor.js"
},
"testRegex": "(/__tests__/.*|\\.(test|spec))\\.(ts|tsx|js)$",
"testPathIgnorePatterns": [
"\\.snap$",
"<rootDir>/node_modules/"
],
"cacheDirectory": ".jest/cache"
}
}
I don't know what is wrong with the version 3 of react-navigation, but downgrading react-navigation onto
v2.18.3
resolved the issue.