我正在尝试将以前的路线名称获取到当前屏幕。因为根据之前的屏幕名称,我必须在当前屏幕中显示/隐藏一些对象。
为了获取以前的屏幕名称,我尝试了以下
componentDidMount() {
const { navigation } = this.props;
if (navigation.state.params && navigation.state.params.previous_screen) {
console.log('navigation.state.params.previous_screen', navigation.state.params.previous_screen);
}
}
但是,控制台日志中出现
undefined
。
有什么建议吗?
对于 Stack Navigator,我能够通过以下方式动态获取 React-navigation v6 中之前的路由名称:
// `navigation` const is passed to the screen component or from useNavigation()
const routes = navigation.getState()?.routes;
const prevRoute = routes[routes.length - 2]; // -2 because -1 is the current route
注意:这对于动态地将参数传递回上一个屏幕非常有用。但要注意嵌套路由,语法略有不同。
if (prevRoute.name === "<Some Routing Key>") {
navigation.navigate("<Some Routing Key>", params);
}
您需要使用
NavigationActions
goToScreen = () => {
const navigateAction = NavigationActions.navigate({
routeName: 'Profile',
params: { previous_screen: 'Home' }, // current screen
action: NavigationActions.navigate({ routeName: 'Profile' }), // screen you want to navigate to
});
this.props.navigation.dispatch(navigateAction);
};
在您的
onPress
中调用上述函数
<Text onPress={this.goToScreen}>Go to screen</Text>
在您的另一个屏幕中
componentDidMount = () => {
const { navigation } = this.props;
if (navigation.state.params && navigation.state.params.previous_screen) {
this.setState({
previous_screen: navigation.state.params.previous_screen
});
} else {
console.log("ERROR");
}
};
功能版
const goToScreen = () => {
// assuming that navigation is passed in props
props.navigation.navigate('Settings', {
previous_screen: 'Home'
})
}
并访问参数,例如
const Settings = ({ route }) => {
const { previous_screen } = route.params;
return ....
}
我找到了从当前屏幕找到先前路线(屏幕)名称的正确方法
props.navigation.dangerouslyGetParent().state.routes
您将从导航堆栈中获取屏幕列表(数组)。例如
输出在这里
Array(0) [, …]
0:Object {routeName: "ROUNTE_NAME", key: "id-158*****6785-1"}
1:Object {params: Object, routeName: "Screen1", key: "Screen1"}
2:Object {params: Object, routeName: "Screen2", key: "Screen2"}
谢谢大家 - K00L ;)
使用导航ref,您可以访问根状态。
此块有助于检查目标路线是否位于嵌套导航/路线内
(currentRoute?.state?.index > -1 && currentRoute?.state?.routes) ? currentRoute?.state?.routes?.[currentRoute?.state?.index]
const getRecentRoutes = ()=> {
const rootState = navigationContainerRef.current?.getRootState();
const routes = rootState?.routes;
const previousRoute = routes?.[routes?.length - 2];
const currentRoute = routes?.[routes?.length - 1];
return {
currentRoute: (currentRoute?.state?.index > -1 && currentRoute?.state?.routes) ? currentRoute?.state?.routes?.[currentRoute?.state?.index] : currentRoute,
previousRoute: (previousRoute?.state?.index > -1 && previousRoute?.state?.routes) ? previousRoute?.state?.routes?.[previousRoute?.state?.index] : previousRoute,
};
};
我使用了以下方法。这可能不是最好的方法,但确实有效。
let routes = this.props.navigation.dangerouslyGetState().routes[0].state.history;
for (let idx = routes.length - 1; idx >= 0; idx--) {
if (routes[idx].type == 'route') {
let route = routes[idx].key;
this.props.navigation.navigate(route.substr(0, route.indexOf('-')));
break;
}
}
const navigateAction = NavigationActions.navigate({
routeName: 'Profile',
action: NavigationActions.navigate({ routeName: 'Profile', params: { previous_screen: 'Home' } }),
});
this.props.navigation.dispatch(navigateAction);
使用
react-navigation
v5,您可以使用路线和索引递归导航状态以查找当前路线。一旦找到当前路线(没有任何子路线的对象),您可以从索引中减去 1 以获得上一个路线。
实现此目的的代码看起来像这样
const getPreviousRouteFromState = (route: NavigationRoute) => {
let checkRoute = null
if (route.state && route.state.index > -1 && route.state.routes) {
checkRoute = route.state.routes[route.state.index]
if (checkRoute.state && checkRoute.state.routes) {
return getPreviousRouteFromState(checkRoute)
}
const previousRouteIndex = route.state.index - 1
if (previousRouteIndex > -1) {
checkRoute = route.state.routes[previousRouteIndex]
}
}
return checkRoute
}
这个策略有一些限制——由于堆栈的限制,它会在导航回来时返回当前路线。切换堆栈时它还会返回当前屏幕。
在
app.js | index.js
中定义一些函数。表示初始屏幕
setActiveScreen = (activeScreen) => {
const previousScreen = this.state.activeScreen
this.setState({activeScreen: activeScreen, previousScreen: previousScreen})
}
goBackScreen = () => {
this.setState({activeScreen: this.state.previousScreen});
}
并将此功能传递到导航屏幕
<Stack.Screen >
{(props) => <ComponentScreen goBackScreen={this.goBackScreen} setActiveScreen={this.setActiveScreen} /> }
</Stack.Screen>
然后在屏幕中使用
goBackScreen
之前运行 navigation.goBack()
<TouchableOpacity onPress={() => {
this.props.goBackScreen()
this.props.navigation.goBack();
}}><Text>Click</Text> </TouchableOpacity>
Note
:现在您可以在activeScreen中获取之前的屏幕名称。这只是可能性的一个例子。你也可以尝试自己的想法
或者你可以在params中传递上一个屏幕
navigation.navigate("home", {params: {previousScreen: '{{pass the currentScreen name}}'
然后下一个屏幕你可以通过
console.log(this.props.route.params)
获得它
const routes = navigation.getState()?.routes;
const prevRoute = routes[routes.length - 2];
if (prevRoute && prevRoute.name === 'previousScreen') {
navigation.navigate('previousScreen');
} else {
navigation.navigate('nextScreen');
}
在我的一个项目中,我尝试使用索引和路线获取以前的屏幕名称。
我使用的是react-navigation 5.x版本。
const { index, routes } = this.props.navigation.getState();
if( index && routes && routes[index-1].name){
const previousScreenName = routes[index-1].name;
... code goes here
}