我使用react-native-code-push。这是:
此插件为CodePush服务提供客户端集成, 允许您轻松地为React添加动态更新体验 原生应用程序。
但是在react-native-navigation这样的导航的一些原生实现中,没有任何根组件。 该应用程序将开始调用这样的函数:
// index.js
import { Navigation } from 'react-native-navigation';
Navigation.startTabBasedApp({
tabs: [
{
label: 'One',
screen: 'example.FirstTabScreen', // this is a registered name for a screen
icon: require('../img/one.png'),
selectedIcon: require('../img/one_selected.png'), // iOS only
title: 'Screen One'
},
{
label: 'Two',
screen: 'example.SecondTabScreen',
icon: require('../img/two.png'),
selectedIcon: require('../img/two_selected.png'), // iOS only
title: 'Screen Two'
}
]
});
// or a single screen app like:
Navigation.registerComponent('example.MainApplication', () => MainComponent);
Navigation.startSingleScreenApp({
screen: {
screen: 'example.MainApplication',
navigatorButtons: {},
navigatorStyle: {
navBarHidden: true
}
},
})
因为没有根组件,所以我不知道应该在哪里调用CodePush
,因为通常我应该使用CodePush将整个根组件包装成更高阶的组件。
我以前做的是:
// index.js
class MyRootComponent extends Component {
render () {
return <MainNavigator/> // a navigator using react-navigation
}
}
let codePushOptions = {
checkFrequency: CodePush.CheckFrequency.ON_APP_RESUME,
installMode: CodePush.InstallMode.ON_NEXT_RESUME
}
export default CodePush(codePushOptions)(MyRootComponent)
有没有正确的方法来解决这个问题!?
我知道我可以这样做:
Navigation.registerComponent('example.MainApplication', () => CodePush(codePushOptions)(RootComponent));
Navigation.startSingleScreenApp({
screen: {
screen: 'example.MainApplication',
navigatorButtons: {},
navigatorStyle: {
navBarHidden: true
}
},
})
然后我应该使用导航器 来投射我的根组件,它看起来不是一个好主意。我认为这个问题可能是我正在寻找的最佳实践。
更新
我认为在react-native-navigation
中的stacknavigator中注册tab导航器有一些复杂问题,至少我无法解决这个问题。 tabBasedApp
中带有react-native-navigation
的示例react-native-code-push
将是我需要的所有内容。
答案 0 :(得分:4)
感谢以前的代码片段。我能够在应用程序恢复上获得代码推送检查,并使用带有以下代码的react-native-navigation V2立即进行更新,而无需使用codePush的包装器组件。这是应用启动逻辑的相关部分。
Navigation.events().registerAppLaunchedListener(() => {
console.log('Navigation: registerAppLaunchedListener ')
start()
})
function checkCodePushUpdate () {
return codePush.sync({
checkFrequency: codePush.CheckFrequency.ON_APP_RESUME,
installMode: codePush.InstallMode.IMMEDIATE,
deploymentKey: CODEPUSH_KEY,
})
}
function start () {
checkCodePushUpdate ()
.then(syncStatus => {
console.log('Start: codePush.sync completed with status: ', syncStatus)
// wait for the initial code sync to complete else we get flicker
// in the app when it updates after it has started up and is
// on the Home screen
startApp()
return null
})
.catch(() => {
// this could happen if the app doesn't have connectivity
// just go ahead and start up as normal
startApp()
})
}
function startApp() {
AppState.addEventListener('change', onAppStateChange)
startNavigation()
}
function onAppStateChange (currentAppState) {
console.log('Start: onAppStateChange: currentAppState: ' + currentAppState)
if (currentAppState === 'active') {
checkCodePushUpdate()
}
}
function startNavigation (registered) {
console.log('Start: startNavigation')
registerScreens()
Navigation.setRoot({
root: {
stack: {
children: [{
component: {
name: 'FirstScreen,
},
}],
},
},
})
}
答案 1 :(得分:2)
尽管这是针对RNN v2的,但我还是这样工作的
// index.js
import App from './App';
const app = new App();
// App.js
import CodePush from 'react-native-code-push';
import { Component } from 'react';
import { AppState } from 'react-native';
import { Navigation } from 'react-native-navigation';
import configureStore from './app/store/configureStore';
import { registerScreens } from './app/screens';
const appStore = configureStore();
registerScreens(appStore, Provider);
const codePushOptions = {
checkFrequency: CodePush.CheckFrequency.ON_APP_RESUME,
updateDialog: true,
installMode: CodePush.InstallMode.IMMEDIATE
};
export default class App extends Component {
constructor(props) {
super(props);
// Set app state and listen for state changes
this.appState = AppState.currentState;
AppState.addEventListener('change', this.handleAppStateChange);
this.codePushSync();
Navigation.events().registerAppLaunchedListener(() => {
this.startApp();
});
}
handleAppStateChange = nextAppState => {
if (this.appState.match(/inactive|background/) && nextAppState === 'active') {
this.handleOnResume();
}
this.appState = AppState.currentState;
};
codePushSync() {
CodePush.sync(codePushOptions);
}
handleOnResume() {
this.codePushSync();
...
}
startApp() {
Navigation.setRoot({
root: {
stack: {
children: [
{
component: {
name: 'MyApp.Login'
}
}
]
}
}
});
}
}
// app/screens/index.js
import CodePush from 'react-native-code-push';
import { Navigation } from 'react-native-navigation';
import Login from './Login';
function Wrap(WrappedComponent) {
return CodePush(WrappedComponent);
}
export function registerScreens(store, Provider) {
Navigation.registerComponentWithRedux(
'MyApp.Login',
() => Wrap(Login, store),
Provider,
store.store
);
...
}
答案 2 :(得分:0)
我自己找到了答案。 看看这个示例项目结构:
.
├── index.js
├── src
| └── app.js
└── screens
├── tab1.html
└── tab2.html
您可以在code-push
注册index.js
。
//index.js
import { AppRegistry } from 'react-native';
import App from './src/app';
import CodePush from 'react-native-code-push'
let codePushOptions = {
checkFrequency: CodePush.CheckFrequency.ON_APP_RESUME,
installMode: CodePush.InstallMode.ON_NEXT_RESUME
}
AppRegistry.registerComponent('YourAppName', () => CodePush(codePushOptions)(App));
现在您可以react-native-navigation
开始app.js
,如下所示:
import {Navigation} from 'react-native-navigation';
import {registerScreens, registerScreenVisibilityListener} from './screens';
registerScreens();
registerScreenVisibilityListener();
const tabs = [{
label: 'Navigation',
screen: 'example.Types',
icon: require('../img/list.png'),
title: 'Navigation Types',
}, {
label: 'Actions',
screen: 'example.Actions',
icon: require('../img/swap.png'),
title: 'Navigation Actions',
}];
Navigation.startTabBasedApp({
tabs,
tabsStyle: {
tabBarBackgroundColor: '#003a66',
tabBarButtonColor: '#ffffff',
tabBarSelectedButtonColor: '#ff505c',
tabFontFamily: 'BioRhyme-Bold',
},
appStyle: {
tabBarBackgroundColor: '#003a66',
navBarButtonColor: '#ffffff',
tabBarButtonColor: '#ffffff',
navBarTextColor: '#ffffff',
tabBarSelectedButtonColor: '#ff505c',
navigationBarColor: '#003a66',
navBarBackgroundColor: '#003a66',
statusBarColor: '#002b4c',
tabFontFamily: 'BioRhyme-Bold',
}
});