[英]React-native app is being restarted on every navigation when integrated with native app
我們正在嘗試將新的React Native應用程序集成到現有的原生Android應用程序中。 遵循RN官方文檔,我們設法使其工作,但有一些關於導航的問題。
我們有原生和非原生(JS)屏幕,我們需要一種在所有屏幕之間導航的好方法,無論屏幕是否為原生屏幕。
我們嘗試采用本機導航和react-native-navigation來查看是否有任何地址我們的問題,但沒有一個實際工作。
目前,我們已經注冊了所有我們的RN屏幕,如下所示:
const provide = (store, Screen) => {
return props => (
<Provider store={store}>
<Screen {...props} />
</Provider>
);
};
const store = configureStore();
AppRegistry.registerComponent('Home', () => provide(store, HomeComponent));
我們還創建了一個名為“Navigator”的本機模塊,它具有名為openComponent
導航方法,可接受屏幕名稱及其道具。 以下是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());
}
}
然后,每當我們想要在RN側導航時,我們只需使用目標屏幕道具調用我們的自定義導航器。
當前方法的問題在於,每當我們導航到基於RN的屏幕時,RN部件正在重新啟動,這導致Redux存儲空。
這里我們的ReactActivity.java類的“onCreate”方法如何:
@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);
}
實際上,對於你的問題案例,你應該在Gitlab或Github上上傳一小部分你的項目並將其鏈接放在這里,因此我們可以提供更好的幫助。
事實上,我是一名JavaScript
, React
, React Native
開發人員,我無法幫助原住民,但絕對,我相信你和你的同事為你的應用選擇了錯誤的方式。
React Native
是一個不穩定的JavaScript
項目,它具有不穩定的本機代碼,這些代碼正在及時更改,因此您應該只使用JavaScript
編寫所有功能。 就像Sophie Albert在本文中所說的那樣,他們想對React Native
進行大的改動,所以,用JavaScript
編寫的所有代碼都不是本機代碼(Java,Objective C)。
起初,我相信你選擇react-native-navigation
是錯誤的。 你為什么不使用react-navigation
?
因為基於JavaScript
99.7%的react-navigation
和Facebook團隊改變原生方面,不會影響您的項目,開發和調試非常容易。 絕對,你可以使用像Redux
這樣的每個趨勢庫,因為你的項目基於JavaScript
。
我和我的同事正在為Sheypoor開發一個大規模的React Native
應用程序,除了基於JavaScript
所有應用程序的啟動屏幕,在我們的輸入測試中,我們甚至沒有得到一次崩潰或錯誤或不需要的重啟。
如果可以,請將導航回滾到完整的JavaScript
導航庫,例如我們選擇的react-navigation
。 如果你上傳了一個復制庫,我可以比這種情況更好地幫助你。 但我放了一些代碼結構來幫助你回滾到react-navigation
:
我們項目的index.js
:
import { AppRegistry } from 'react-native';
import App from './app/App';
import { name as appName } from './app.json';
AppRegistry.registerComponent(appName, () => App);
我們的應用程序的根文件, 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;
RootNavigation.js
文件,但它RootNavigation.js
用於我們之前的提交。 由於其復雜性,我不會把更新的版本:
import { createSwitchNavigator } from 'react-navigation';
import { Loading, Dashboard, SignInStack, ListingManagement } from './screens';
const RootNavigation = createSwitchNavigator(
{
Loading,
SignInStack,
Dashboard,
ListingManagement
},
{
initialRouteName: 'SignInStack'
}
);
export default RootNavigation;
最后, 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"
]
}
}
使用這些代碼和配置,我們甚至沒有給出一個錯誤。
在ReactActivity.java
可以檢查Bundle savedInstanceState
...為了控制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);
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.