This.props.navigation.navigate () не работает (с использованием WithNavigation)

Я реализовал всплывающий компонент в заголовке с кнопкой «Дополнительные параметры». Эта кнопка доступна только на UserProfileScreen. При нажатии на нее вы видите две кнопки: «Настройки» и «Выйти». Проблема связана с кнопкой «Настройки».

Ожидаемое поведение: Нажмите кнопку Настройки -> вызывается this.props.navigation.navigate ('SettingsNavigator') -> Отображается экран настроек

Фактическое поведение: Нажмите кнопку «Настройки» -> вызывается console.warn («перейти в настройки») и больше ничего (вы не перенаправляетесь на экран настроек).

SettingsNavigator.js

import React from 'react';
import { createStackNavigator } from 'react-navigation';

import SettingsScreen from './SettingsScreen';
import EditProfileScreen from './EditProfileScreen';
import RemoveProfileScreen from './RemoveProfileScreen';

const SettingsNavigator = createStackNavigator({
    SettingsScreen: SettingsScreen,
    EditProfile: EditProfileScreen,
    RemoveProfile: RemoveProfileScreen
}, {
    initialRouteName: 'SettingsScreen'
});

export default SettingsNavigator;

optionHeaderButton.js

import { withNavigation } from 'react-navigation';
...

class OptionsHeaderButton extends Component {

    ...

    navigateToSettings = () => {
        console.warn('go to settings')
        this.props.navigation.navigate('SettingsNavigator');
    }

    render() {
    return(
        <Menu onSelect = {value => {
            switch(value) {
                case 'Settings':
                    this.navigateToSettings();
                    break;
                case 'Logout':
                    this.onLogOutPress();
                    break;
            }
        }}>

            <MenuTrigger>
                <Icon name = 'dots-vertical' size = {24} color = {text}/>
            </MenuTrigger>

            <MenuOptions style = {optionsHeaderButtonStyle.menuWrapper}>

                <MenuOption value = {'Settings'}>
                    <View style = {optionsHeaderButtonStyle.optionWrapper}>
                        <View style = {optionsHeaderButtonStyle.optionIcon}>
                            <IconSimpleLine name = 'settings' size = {12} color = {text}/>
                        </View>
                        <Text style = {[optionsHeaderButtonStyle.option, optionsHeaderButtonStyle.lastOption]}>
                            Settings
                        </Text>
                    </View>
                </MenuOption>

                <MenuOption value = {'Logout'}>
                    <View style = {optionsHeaderButtonStyle.optionWrapper}>
                        <View style = {optionsHeaderButtonStyle.optionIcon}>
                            <IconSimpleLine name = 'logout' size = {12} color = {text}/>
                        </View>
                        <Text style = {[optionsHeaderButtonStyle.option, optionsHeaderButtonStyle.lastOption]}>
                            Logout
                        </Text>
                    </View>
                </MenuOption>

            </MenuOptions>

        </Menu>
    )
}
}

export default withNavigation(OptionsHeaderButton);

OptionsHeaderButton вложен в компонент заголовка, который вложен в компонент UserProfile.

Насколько мне известно, используя withNavigation(), я могу вызывать navigation.navigate() из любого компонента. Так почему это не работает?

Обновлено:

После расследования я обнаружил, что эта проблема связана с ошибкой React Navigation, обнаруженной в апреле 2017 года. Это означает, что вы можете использовать navigation.navigate() только внутри одного стека. Но я не могу найти никакой информации об исправлении этой ошибки.

хм, есть обновления?

DevAS 12.07.2019 04:29
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Навигация по приложениям React: Исчерпывающее руководство по React Router
Навигация по приложениям React: Исчерпывающее руководство по React Router
React Router стала незаменимой библиотекой для создания одностраничных приложений с навигацией в React. В этой статье блога мы подробно рассмотрим...
Массив зависимостей в React
Массив зависимостей в React
Все о массиве Dependency и его связи с useEffect.
8
1
5 385
4

Ответы 4

вместо навигатора нужно передать псевдоним.

this.props.navigation.navigate('SettingsSecreen');

К сожалению, это не помогло.

Ivan Burzakovskiy 14.01.2019 14:51

попробуй это:

import { NavigationActions, withNavigation } from 'react-navigation';



navigateToSettings = () => {
  const navigateAction = NavigationActions.navigate({ routeName: 'SettingsScreen' });
  this.props.navigation.dispatch(navigateAction);
}

К сожалению, это тоже не помогло

Ivan Burzakovskiy 14.01.2019 15:32

У меня была эта проблема, но я немного по-другому подключил свой App.js, используя навигацию по стеку и навигацию по ящику (и переключение навигации для аутентификации) - в основном следовал документации по реагированию на навигацию:

App.js

const AuthStack = createStackNavigator({ Login: Login }, { headerMode: 'none' });
const ActivityStack = createStackNavigator({ Activity: ActivityScreen}, {headerMode: 'none'});

// setup my routing & config here

export default createAppContainer(createSwitchNavigator(
{
   Auth: AuthStack,
   ActivityStack: ActivityStack,
},
{
   intitalRouteName: 'Auth',
},
));

На экране, на котором я хочу перемещаться, я подключаю конструктор следующим образом (для привязки функции навигации):

FirstScreen.js

export default class FirstScreen extends React.Component {
  constructor(props) {
    super(props);

    this.navigateToScreen = this.navigateToScreen.bind(this);
  }

state = {
   // state items here
}

  navigateToScreen(screenName) {
    this.props.navigation.navigate(screenName);
  }

  render() {
    return (
      <View style = {styles.container}>
        <TouchableOpacity style = {styles.button} onPress= 
              {this.navigateToScreen("Activity")}>
          <Text style = {styles.loginText}>
            ADD ACTIVITY
          </Text>
        </TouchableOpacity>
      </View>

Обратите внимание, как я вызываю навигацию, я передаю только псевдоним маршрута, который я дал ранее в файле App.js:

    Activity: ActivityStack,

Поэтому я бы написал this.navigateToScreen("Activity") из вызывающей точки, передав псевдоним, а не экранное имя или имя стека.

Это правильно перемещается на экран и использует навигацию по стеку, которую я определил ранее в App.js.

Надеюсь, это имеет смысл (иерархия родительских и дочерних элементов достигается за счет вложения различных функций навигации, таких как переключатель, стек и ящик, для достижения желаемых результатов.

в react-navigation Версия: 5.x с навигацией не работает. Чтобы решить эту проблему, попробуйте это.

import { useNavigation } from '@react-navigation/native';
const navigation = useNavigation();
navigation.navigate("DetailsScreen")

не нужно деформировать компонент в withNavigation.

Надеюсь, это поможет.

Другие вопросы по теме