Мне нужно имя текущего маршрута или экрана в реакции-навигации, которое я хочу использовать внутри условия if, чтобы внести некоторые изменения.
React - это такая неразбериха со всеми изменениями между версиями. В документации ничего из этого не упоминается, и код кажется трудным для понимания, мне интересно, как люди вообще придумали эти (старые) решения.
каким-либо способом для 'wix / react-native-navigation', чтобы получить текущий экран?
При использовании "react-navigation": "^3.0.8" и DrawerNavigator к нему можно получить доступ из объекта this.props, используя
this.props.activeItemKey
с DrawerNavigator он работает, вы используете то же самое?
Если вы используете вложенные навигаторы, например StackNavigator внутри DrawerNavigator, и вам нужен activeItemKey внутри ящиков contentComponent, как бы вы его получили?
для одного маршрута это работает для меня this.props.navigation.state.routeName
Вы можете поймать это как следующий код:
this.props.navigation.state.routeName
Этот ответ работает с StackNavigator. Предыдущий ответ this.props.activeItemKey не работает.
Идеально работает с навигатором верхней вкладки материала в defaultNavigationOptions.
Привет, надеюсь, у тебя все хорошо. Не могли бы вы взглянуть на мой вопрос? stackoverflow.com/questions/66548327/…, спасибо
как мне проверить текущее имя маршрута ящика в дочернем стеке
Если вы используете вложенные навигаторы, вы можете использовать этот код для получения текущего состояния активного экрана.
import { NavigationState } from 'react-navigation';
const getActiveRouteState = function (route: NavigationState): NavigationState {
if (!route.routes || route.routes.length === 0 || route.index >= route.routes.length) {
return route;
}
const childActiveRoute = route.routes[route.index] as NavigationState;
return getActiveRouteState(childActiveRoute);
}
Использование:
const activeRoute = getActiveRouteState(this.props.navigation.state);
Я использую это, когда мне нужно получить текущее состояние активного экрана из NavigationDrawer.
Я думаю, этот ответ более общий
Как вы вводите маршрут в специальный ящик?
Откуда приходит NavigationState?
@Hugo NavigationState - это импорт из react-navigation
У меня есть несколько TabNavigator, вложенных в BottomTabNavigator. Я получаю текущий маршрут TabNavigator с:
const pathAndParams = props.navigation.router.getPathAndParamsForState(props.navigation.state) || {}
const activePath = pathAndParams.path
Зарегистрируйте ?NavigationService.js, см. детали документа в Навигация без навигационной опоры
<App
ref = {navigatorRef => {
NavigationService.setTopLevelNavigator(navigatorRef);
}}
/>
функция рекурсии
function getCurrentRoute(nav){
if (Array.isArray(nav.routes)&&nav.routes.length>0){
return getCurrentRoute(nav.routes[nav.index])
}else {
return nav.routeName
}
}
getCurrentRoute(NavigationService.getNavigator().state.nav)
Для реакции-навигации v5 вы можете использовать хук useNavigationState -
import {useNavigationState} from '@react-navigation/native';
const state = useNavigationState(state => state);
const routeName = (state.routeNames[state.index]);
console.info(routeName);
Для реакции-навигации v5:
import {useRoute} from '@react-navigation/native';
const route = useRoute();
console.info(route.name);
Вы не указали, в каком месте мне следует использовать этот метод useRoute (). Я получаю, что хуки можно вызывать только внутри тела функционального компонента.
Как идентифицировать этот сценарий? Переход прямо к экрану контактов. И переход к экрану контактов через главный экран.
как мне проверить текущий маршрут ящика?
Это отлично работает в react-navigation v5.x
this.props.route.name
В React Navigation v5 я смог извлечь текущее имя маршрута с помощью следующего подхода:
import { useNavigationState } from '@react-navigation/native'
const routes = useNavigationState(state => state.routes)
const currentRoute = routes[routes.length -1].name
console.info('currentRoute: ',currentRoute)
const routeNameRef = React.createRef();
<NavigationContainer
ref = {navigationRef}
onReady = {() => routeNameRef.current = navigationRef.current.getCurrentRoute().name}
onStateChange = {() => {
const previousRouteName = routeNameRef.current
const currentRouteName = navigationRef.current.getCurrentRoute().name
if (previousRouteName !== currentRouteName) {
// Do something here with it
}
// Save the current route name for later comparision
routeNameRef.current = currentRouteName
}}
>
{/* ... */}
</NavigationContainer>
);
export function getCurrentRouteName(action) {
return routeNameRef;
}
Вы можете импортировать функцию getCurrentRouteName и использовать ее, чтобы получить имя текущего маршрута и его работу во всех вложенных навигаторах в React Navigation 5.
Остерегайтесь этого Попался
this.props.navigation.state.routeName работает только в react-navigation 4, но react-navigation 5 его не поддерживает.
Текущее имя маршрута может быть получено с помощью redux:
-Компонент навигатора передает объект маршрута как опору дочернему компоненту
-Дочерний компонент получает реквизиты и может найти имя маршрута в route.name
-Чтобы получить обновленное имя маршрута при изменении экрана, вы можете использовать прослушиватель событий фокус при навигации
<====== Родительский компонент, в котором реализована навигация ======>
import React from "react";
import { createMaterialTopTabNavigator } from "@react-navigation/material-top-
tabs";
import ChildScreen from "../screens/Home/childScreen";
const Tab = createMaterialTopTabNavigator();
const ParentNavigations = () => {
return (
<Tab.Navigator
>
<Tab.Screen name = "ChildScreen" component = {ChildScreen} />
</Tab.Navigator>
);
};
export default ParentNavigations;
<===== Дочерний компонент =====>
import React, { useEffect } from "react";
import { View, StyleSheet } from "react-native";
import { useDispatch } from "react-redux";
import ActionTypes from "../../store/actions/ActionsTypes";
const ChildScreen = ({ navigation, route }) => {
const dispatch = useDispatch();
useEffect(() => {
const unsubscribe = navigation.addListener("focus", () => {
dispatch({ type: ActionTypes.SETROUTE, payload: route.name }); // every time when screen gets focued it will update the route through redux
});
return unsubscribe;
}, [navigation, route]);
return (
<View style = {styles.container}>
<Text>Hello</Text>
</View>
);
};
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: "#0C0B0B",
},
});
export default ChildScreen;Если вы просто хотите увидеть, сфокусирован ли текущий экран, вы можете использовать navigation.isFocused (). https://reactnavigation.org/docs/navigation-prop/#isfocused
Пример:
_backAction() {
const { navigation } = this.props;
if (navigation.isFocused()) {
this.setState({
isLeavingApp: true,
});
}
}
Это сработало для меня (я сделал это в моем навигационном ящике)!
const getCurrentRoute = nav => {
if (Array.isArray(nav.routes) && nav.routes.length > 0) {
return getCurrentRoute(nav.routes[nav.index]);
} else {
return nav.routeName;
}
};
const currentNavigation = getCurrentRoute(this.props.navigation.state);С версией 5.x лучший способ на данный момент - getFocusedRouteNameFromRoute
import { getFocusedRouteNameFromRoute } from '@react-navigation/native';
export default function Stack(route) {
// If the focused route is not found, we need to assume it's the initial screen
// This can happen during if there hasn't been any navigation inside the screen
// In our case, it's "Feed" as that's the first screen inside the navigator
const routeName = getFocusedRouteNameFromRoute(route) ?? 'Feed';
return <> ..... </>
}
import { useNavigation } from '@react-navigation/native';
const App = () => {
const navigation = useNavigation();
const { dangerouslyGetState } = useNavigation();
const { index, routes } = dangerouslyGetState()
console.info(routes[index].name);
return(
<>
</>
)
};
это сработало для меня, попробуйте это ..
const getCurrentRouteName = () => {
let _index = props.state.index;
let _routeName = props.state.routeNames;
return _routeName[_index]
}
Для wix / response-native-navigation ниже мое рабочее решение,
import { Navigation } from 'react-native-navigation';
// Create a variable and set the value from navigation events
let navComponent = null
Navigation.events().registerComponentDidAppearListener(event => navComponent = event)
// navComponent will have the following structure
{"componentId": "Component9", "componentName": "HomeScreen", "componentType": "Component", "passProps": {}}
Это можно получить из navigationRef, прикрепленного к контейнеру навигации. Где navigationRef - исх.
export const navigationRef = React.createRef()
<NavigationContainer
ref = {navigationRef}
>
<Navigator />
</NavigationContainer>
Затем используйте: const currentRouteName = navigationRef.current.getCurrentRoute().name
В качестве альтернативы в функциональном компоненте можно использовать Ref const navigationRef = React.useRef()
const Home = ({ navigation, route }) => {
// you will see screen key, name and params
console.info("ROUTE", route);
// rest of your code
};
Хотя этот код может ответить на вопрос, предоставление дополнительного контекста относительно того, как и / или почему он решает проблему, улучшит долгосрочную ценность ответа.
Вы также можете использовать это в крючках.
console.info(navigation.dangerouslyGetState());
Для реагирования на родную навигацию 5.x используйте:
props.state.routeNames[props.state.index]
Это пошаговая процедура того, что Джастин Мэтью описал в своем ответе.
Создайте новый файл с именем RootNavigation.js и поместите в него содержимое ниже.
// RootNavigation.js
import * as React from 'react';
export const navigationRef = React.createRef(); // we will access all navigation props by importing this in any of the component
Теперь импортируйте navigationRef из файла RootNavigation.js и назначьте ему ссылку NavigationContainer. После этого шага navigationRef может глобально функционировать как навигационная опора.
// App.js
import { NavigationContainer } from '@react-navigation/native';
import { navigationRef } from './RootNavigation';
export default function App() {
handleNavigationRef = (ref) => {
// DON'T DO navigationRef = ref, cause this will give you "navigationRef is
// read only" error.
navigationRef.current = ref;
}
return (
<NavigationContainer ref = {handleNavigationRef}>
{/* ... */}
</NavigationContainer>
);
}
ИСПОЛЬЗОВАНИЕ
Теперь вы можете импортировать navigationRef в любой файл, даже во вложенный. И можете использовать это, чтобы получить информацию о текущем маршруте и экране.
//SomeNestedComonent.js
import { navigationRef } from "path/to/RootNavigation.js/file";
const route = navigationRef.current?.getCurrentRoute(); //current route object
const currentScreen = route.name; // current screen name
В моем случае мне также нужно было получить индекс нижняя навигация, это был мой метод
import {useNavigationState} from '@react-navigation/native';
тогда
const routes = useNavigationState(state => state.routes);
let place = routes[routes.length - 1];
if (place.name === 'YOUR_BOTTOM_NAV_NAME') {
if (place.state.index === 0) {
//you are in the main screen(BOTTOM_NAV : index 0)
} else {
//else navigate to index 0 screen
navigation.navigate('FirstScreen');
}
} else if (place.name === 'Another_Screen') {
navigation.navigate('navigate_to_the_place_you_want');
} else {
//otherwise come to the first screen
navigation.navigate('FirstScreen');
}
Как это возможно теперь в React-Navigation v5?