在非组件的屏幕之间进行本机导航 class
react-native navigating between screens from non component class
我正在尝试从我的后端 class 像这样在 React 本机屏幕之间导航:
var self = this;
firebase.auth().onAuthStateChanged((user) => {
if (user) {
self.setState({
userID: user.uid,
})
} else{
self.props.navigation.navigate("Login");
}
});
我的后端 class 不是一个组件,因此没有导入到我正在使用的堆栈导航器中。我收到一条错误消息 'self.props.navigation is not an object'.
有人知道我可以解决这个问题吗?谢谢
一个不太好的做法是将 Navigator
定义为 App 实例的 static/class 变量:
const MyNavigator = StackNavigator(...);
export default class MyApp extends Component {
render() {
return <MyNavigator ref={(ref) => MyApp.Navigator = ref}/>
}
}
然后您就可以在任何您想要的地方访问您的导航器及其道具和功能! (例如发送一个返回事件):
import MyApp from '...';
MyApp.Navigator.dispatch(NavigationActions.back());
我个人不喜欢发生在该级别的导航操作,但有时这是必要的。扩展@Dusk 的答案,我知道了一个有助于解决这个问题的模式。你可以在这里找到它
https://github.com/react-community/react-navigation/issues/1439#issuecomment-303661539
我们的想法是您创建一个服务来保存导航器的引用。现在,您可以从应用程序的任何位置导入该服务并访问您的导航器。它保持简洁。
如果您使用的是 react-navigation,那么您可以通过 Navigation Service 实现此目的
创建一个名为 NavigationService 的文件并在其中添加以下代码
import { NavigationActions, StackActions } from 'react-navigation';
let navigator;
function setTopLevelNavigator(navigatorRef) {
navigator = navigatorRef;
}
function navigate(routeName, params) {
navigator.dispatch(
NavigationActions.navigate({
routeName,
params
})
);
}
function goBack(routeName, params) {
navigator.dispatch(
StackActions.reset({
index: 0,
actions: [
NavigationActions.navigate({
routeName,
params
})
]
})
);
}
function replace(routeName, params) {
navigator.dispatch(
StackActions.replace({
index: 0,
actions: [
NavigationActions.navigate({
routeName,
params
})
]
})
);
}
function pop() {
navigator.dispatch(StackActions.pop());
}
function popToTop() {
navigator.dispatch(StackActions.popToTop());
}
// add other navigation functions that you need and export them
export default {
navigate,
goBack,
replace,
pop,
popToTop,
setTopLevelNavigator
};
现在将此文件导入您的 app.js 并设置 TopLevelNavigator,您的 app.js 将看起来像这样
import React, { Component } from 'react';
import NavigationService from './routes/NavigationService';
export default class App extends Component {
constructor() {
super();
}
render() {
return (
<View style={{ flex: 1, backgroundColor: '#fff' }}>
<AppNavigator
ref={navigatorRef => {
NavigationService.setTopLevelNavigator(navigatorRef);
}}
/>
</View>
);
}
}
现在一切顺利,您可以在任何地方导入 NavigationService,您可以在任何组件和非组件文件中像这样使用它
import NavigationService from 'path to the NavigationService file';
/* you can use any screen name you have defined in your StackNavigators
* just replace the LogInScreen with your screen name and it will work like a
* charm
*/
NavigationService.navigate('LogInScreen');
/*
* you can also pass params or extra data into the ongoing screen like this
*/
NavigationService.navigate('LogInScreen',{
orderId: this.state.data.orderId
});
我正在尝试从我的后端 class 像这样在 React 本机屏幕之间导航:
var self = this;
firebase.auth().onAuthStateChanged((user) => {
if (user) {
self.setState({
userID: user.uid,
})
} else{
self.props.navigation.navigate("Login");
}
});
我的后端 class 不是一个组件,因此没有导入到我正在使用的堆栈导航器中。我收到一条错误消息 'self.props.navigation is not an object'.
有人知道我可以解决这个问题吗?谢谢
一个不太好的做法是将 Navigator
定义为 App 实例的 static/class 变量:
const MyNavigator = StackNavigator(...);
export default class MyApp extends Component {
render() {
return <MyNavigator ref={(ref) => MyApp.Navigator = ref}/>
}
}
然后您就可以在任何您想要的地方访问您的导航器及其道具和功能! (例如发送一个返回事件):
import MyApp from '...';
MyApp.Navigator.dispatch(NavigationActions.back());
我个人不喜欢发生在该级别的导航操作,但有时这是必要的。扩展@Dusk 的答案,我知道了一个有助于解决这个问题的模式。你可以在这里找到它
https://github.com/react-community/react-navigation/issues/1439#issuecomment-303661539
我们的想法是您创建一个服务来保存导航器的引用。现在,您可以从应用程序的任何位置导入该服务并访问您的导航器。它保持简洁。
如果您使用的是 react-navigation,那么您可以通过 Navigation Service 实现此目的
创建一个名为 NavigationService 的文件并在其中添加以下代码
import { NavigationActions, StackActions } from 'react-navigation';
let navigator;
function setTopLevelNavigator(navigatorRef) {
navigator = navigatorRef;
}
function navigate(routeName, params) {
navigator.dispatch(
NavigationActions.navigate({
routeName,
params
})
);
}
function goBack(routeName, params) {
navigator.dispatch(
StackActions.reset({
index: 0,
actions: [
NavigationActions.navigate({
routeName,
params
})
]
})
);
}
function replace(routeName, params) {
navigator.dispatch(
StackActions.replace({
index: 0,
actions: [
NavigationActions.navigate({
routeName,
params
})
]
})
);
}
function pop() {
navigator.dispatch(StackActions.pop());
}
function popToTop() {
navigator.dispatch(StackActions.popToTop());
}
// add other navigation functions that you need and export them
export default {
navigate,
goBack,
replace,
pop,
popToTop,
setTopLevelNavigator
};
现在将此文件导入您的 app.js 并设置 TopLevelNavigator,您的 app.js 将看起来像这样
import React, { Component } from 'react';
import NavigationService from './routes/NavigationService';
export default class App extends Component {
constructor() {
super();
}
render() {
return (
<View style={{ flex: 1, backgroundColor: '#fff' }}>
<AppNavigator
ref={navigatorRef => {
NavigationService.setTopLevelNavigator(navigatorRef);
}}
/>
</View>
);
}
}
现在一切顺利,您可以在任何地方导入 NavigationService,您可以在任何组件和非组件文件中像这样使用它
import NavigationService from 'path to the NavigationService file';
/* you can use any screen name you have defined in your StackNavigators
* just replace the LogInScreen with your screen name and it will work like a
* charm
*/
NavigationService.navigate('LogInScreen');
/*
* you can also pass params or extra data into the ongoing screen like this
*/
NavigationService.navigate('LogInScreen',{
orderId: this.state.data.orderId
});