react framework developer crear con app javascript android react-native react-native-android react-native-navigation

javascript - framework - La aplicación React-native se reinicia en cada navegación cuando se integra con la aplicación nativa



react native download (2)

En ReactActivity.java se puede verificar el Bundle savedInstanceState

... para controlar cuándo se está instanciando la aplicación React:

@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); /* it''s always NULL on first run */ if (savedInstanceState == null) { Bundle initialProperties = new Bundle(); initialProperties.putString("loginToken", HJSession.getSession().getSessionId()); initialProperties.putString("username", HJSession.getSession().getUserName()); initialProperties.putString("userId", HJSession.getSession().getUserId().toString()); String moduleName = "topics"; Bundle bundle = getIntent().getExtras(); if (bundle != null) { moduleName = bundle.getString("moduleName"); try { String extra = bundle.getString("extra"); initialProperties.putString("extra", extra); } catch (Exception e) { Crashlytics.logException(e.getMessage()); Log.e("ReactActivity", e.getMessage()); } } mReactRootView = new ReactRootView(this); mReactInstanceManager = ReactInstanceManager.builder() .setApplication(getApplication()) .setJSMainModulePath("index") .addPackages(Arrays.<ReactPackage>asList( new MainReactPackage(), new RNFirebasePackage(), new RNFirebaseMessagingPackage(), new RNFirebaseNotificationsPackage(), new RNI18nPackage(), new VectorIconsPackage(), new HJRNPackages(), new NativeNavigationPackage() )) .setUseDeveloperSupport(BuildConfig.DEBUG) .setInitialLifecycleState(LifecycleState.RESUMED) .build(); mReactRootView.startReactApplication(mReactInstanceManager, moduleName, initialProperties); setContentView(mReactRootView); } }

Estamos intentando integrar una nueva aplicación React Native a una aplicación nativa de Android existente. Siguiendo los docs oficiales de RN, logramos que funcionara, pero con algunos problemas relacionados con la navegación.

Tenemos pantallas nativas y no nativas (JS), y necesitamos una buena manera de navegar entre todas las pantallas independientemente de si una pantalla es nativa o no.

Intentamos adoptar native-navigation react-native-navigation para ver si alguna de ellas aborda nuestro problema, pero ninguna de ellas realmente funcionó.

Actualmente, hemos registrado todas nuestras pantallas RN como esta:

const provide = (store, Screen) => { return props => ( <Provider store={store}> <Screen {...props} /> </Provider> ); }; const store = configureStore(); AppRegistry.registerComponent(''Home'', () => provide(store, HomeComponent));

También creamos un Módulo nativo que llamamos "Navegador" que tiene un método de navegación llamado openComponent que acepta el nombre de pantalla y sus accesorios. Aquí es cómo se ve la implementación de openComponent :

// our native module code ... @ReactMethod public void openComponent(String name, String extra) { try { Intent intent = new Intent(this.getReactApplicationContext(), MyReactActivity.class); intent.putExtra("moduleName", name); intent.putExtra("extra", extra); getCurrentActivity().startActivityForResult(intent, 0); } catch (Exception e) { e.printStackTrace(); Crashlytics.logException(e.getCause()); } }

Luego, cuando queremos navegar en el lado RN, simplemente llamamos a nuestro navegador personalizado con los accesorios de la pantalla de destino.

El problema con el enfoque actual es que la parte RN se reinicia cada vez que navegamos a las pantallas basadas en RN, lo que hace que el almacén de Redux esté vacío.

Aquí es cómo se ve nuestro método "onCreate" para nuestra clase ReactActivity.java:

@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); Bundle initialProperties = new Bundle(); initialProperties.putString("loginToken", HJSession.getSession().getSessionId()); initialProperties.putString("username", HJSession.getSession().getUserName()); initialProperties.putString("userId", HJSession.getSession().getUserId().toString()); String moduleName = "topics"; Bundle bundle = getIntent().getExtras(); if (bundle != null) { moduleName = bundle.getString("moduleName"); try { String extra = bundle.getString("extra"); initialProperties.putString("extra", extra); } catch (Exception e) { e.printStackTrace(); Crashlytics.logException(e.getCause()); } } mReactRootView = new ReactRootView(this); mReactInstanceManager = ReactInstanceManager.builder() .setApplication(getApplication()) .setJSMainModulePath("index") .addPackages(Arrays.<ReactPackage>asList( new MainReactPackage(), new RNFirebasePackage(), new RNFirebaseMessagingPackage(), new RNFirebaseNotificationsPackage(), new RNI18nPackage(), new VectorIconsPackage(), new HJRNPackages(), new NativeNavigationPackage() )) .setUseDeveloperSupport(BuildConfig.DEBUG) .setInitialLifecycleState(LifecycleState.RESUMED) .build(); mReactRootView.startReactApplication(mReactInstanceManager, moduleName, initialProperties); setContentView(mReactRootView); }


En realidad, para su caso de pregunta, debe cargar una pequeña escala de su proyecto que tenga este problema en Gitlab o Github y poner su enlace aquí, por lo que podríamos ayudarlo mejor.

De hecho, soy un desarrollador de JavaScript , React , React Native y no puedo ayudar a nadie en el lado nativo, pero definitivamente, creo que usted y sus colegas eligen la forma incorrecta para su aplicación.

React Native es un proyecto de JavaScript inestable que tiene códigos nativos inestables que están cambiando en el tiempo, por lo que debe escribir todas sus características con solo usar JavaScript . Al igual que Sophie Albert dijo en este artículo , Ellos quieren hacer un gran cambio para React Native , por lo tanto, es mejor que todos los códigos se escriban en JavaScript no nativos (Java, Objetivo C).

Al principio, creo que su elección en react-native-navigation fue incorrecta. ¿Por qué no usas react-navigation ?

Debido a que el 99.7% de react-navigation basada en JavaScript y los cambios en el lado nativo de los equipos de Facebook, no afecta su proyecto y el desarrollo y la depuración es muy fácil. Absolutamente, puedes usar todas las bibliotecas de tendencias como Redux , debido a tu proyecto basado en JavaScript .

Mis colegas y yo estamos desarrollando una aplicación React Native gran escala para Sheypoor , excepto en la pantalla de Sheypoor , toda la aplicación basada en JavaScript y en nuestras pruebas de entrada no tuvimos ni un fallo ni un error o un reinicio no deseado.

Si es posible para usted, retroceda su navegación a una biblioteca de navegación de JavaScript completa como react-navigation que elegimos. Si subiste un repositorio de reproducción, podría ayudarte mejor que esta situación. pero puse algo de nuestra estructura de código para ayudarlo a retroceder a react-navigation :

El index.js de nuestro proyecto:

import { AppRegistry } from ''react-native''; import App from ''./app/App''; import { name as appName } from ''./app.json''; AppRegistry.registerComponent(appName, () => App);

El archivo raíz de nuestra aplicación, el archivo App.js :

import React from ''react''; import { Provider } from ''react-redux''; import RootNavigation from ''./RootNavigation''; import { onNavigationStateChange } from ''./utils/routes''; import configureStore from ''./redux/configureStore''; const store = configureStore(); const App = () => ( <Provider store={store}> <RootNavigation onNavigationStateChange={onNavigationStateChange} /> </Provider> ); export default App;

El archivo RootNavigation.js , pero es para nuestros compromisos anteriores no ahora. No pongo la versión más nueva debido a sus complejidades:

import { createSwitchNavigator } from ''react-navigation''; import { Loading, Dashboard, SignInStack, ListingManagement } from ''./screens''; const RootNavigation = createSwitchNavigator( { Loading, SignInStack, Dashboard, ListingManagement }, { initialRouteName: ''SignInStack'' } ); export default RootNavigation;

Y por fin, la versión anterior de package.json :

{ "name": "sheypoor", "version": "0.0.1", "private": true, "scripts": { "start": "node node_modules/react-native/local-cli/cli.js start", "android": "npx react-native run-android", "ios": "npx react-native run-ios", "physical-android": "react-native bundle --platform android --dev false --entry-file index.js --bundle-output android/app/src/main/assets/index.android.bundle --assets-dest android/app/src/main/res", "test": "jest", "eslint": "eslint .", "clean": "react-native-clean-project", "pre-commit": "lint-staged" }, "lint-staged": { "*.js": [ "eslint --fix ." ] }, "dependencies": { "formik": "^1.3.0", "lint-staged": "^7.3.0", "prop-types": "^15.6.2", "react": "16.5.0", "react-native": "0.57.1", "react-native-confirmation-code-field": "^1.2.2", "react-native-vector-icons": "^5.0.0", "react-navigation": "^2.16.0", "react-redux": "^5.0.7", "redux": "^4.0.0", "yup": "^0.26.6" }, "devDependencies": { "babel-eslint": "^9.0.0", "babel-jest": "23.6.0", "babel-plugin-module-resolver": "^3.1.1", "babel-plugin-root-import": "^6.1.0", "eslint": "^5.5.0", "eslint-config-airbnb": "^17.1.0", "eslint-config-prettier": "^3.0.1", "eslint-import-resolver-babel-plugin-root-import": "^1.1.1", "eslint-plugin-flowtype": "^2.50.0", "eslint-plugin-import": "^2.14.0", "eslint-plugin-jsx-a11y": "^6.1.1", "eslint-plugin-prettier": "^2.6.2", "eslint-plugin-react": "^7.11.1", "eslint-plugin-react-native": "^3.3.0", "eslint-plugin-sort-imports-es6-autofix": "^0.3.0", "flow-bin": "^0.78.0", "jest": "23.6.0", "metro-react-native-babel-preset": "0.45.6", "prettier": "^1.14.3", "react-native-clean-project": "^3.0.0", "react-native-config": "^0.11.5", "react-test-renderer": "16.5.0", "redux-devtools-extension": "^2.13.5" }, "jest": { "preset": "react-native" }, "rnpm": { "assets": [ "./app/assets/fonts" ] } }

Con estos códigos y configuraciones, no cometimos ni un error.