ОШИБКА TypeError: неопределенный не является объектом (оценка ‘this.props.navigation.navigate’) при импорте моего компонента в дочерний

#javascript #reactjs #react-native

#javascript #reactjs #react-native

Вопрос:

Я создал компонент меню свертывания и импортировал в него другой компонент, но на экране нет навигации. он показывает ошибку TypeError: undefined не является объектом (оценка ‘this.props.navigation.navigate’). Я не могу перемещаться по экрану по имени метки.

Свернуть код меню

 import React, {useState, useEffect} from 'react';
import {
  View,
  StyleSheet,
  Text,
  LayoutAnimation,
  TouchableOpacity,
} from 'react-native';

import Font from '../constant/fonts';
import Color from '../constant/colors';
import fontF from '../styles/fontfamily';
import Icon from '../styles/icons';

import {heightToDp, widthToDp} from '../constant/utils';
import Size from '../constant/sizes';
import Card from './Cards/card';
import {Divider} from 'react-native-elements';
class CollapseMenu extends React.Component {
  componentDidMount() {
    console.log('navigation', this.props);
  }

  constructor(props) {
    super(props);

    this.state = {
      expanded: false,
    };
    this.handleCollapse = this.handleCollapse.bind(this);
  }

  handleCollapse() {
    const {expanded} = this.state;
    this.setState({expanded: !expanded});
  }
  handleRoute(label) {
    console.log(this.props);
    this.props.navigation.navigate(label);
  }

  render() {
    const {expanded} = this.state;
    return (
      <View>
        <TouchableOpacity onPress={this.handleCollapse}>
          <View style={styles.mainContainer}>
            <View style={[styles.sidebarDesign]}>
              <View style={styles.barIcon}>
                <Icon.SimpleLineIcons name={this.props.item.icon} size={20} />
              </View>
              <View style={styles.barLabel}>
                <Text style={[styles.labelStyle]}>
                  {this.props.item.title.toUpperCase()}
                </Text>
              </View>
              <View style={styles.barIcon}>
                <Icon.SimpleLineIcons
                  name={expanded ? 'arrow-up' : 'arrow-down'}
                  size={20}
                  color={Color.grayDark}
                />
              </View>
            </View>
          </View>
        </TouchableOpacity>

        {this.props.item.subarr.map((child, j) => (
          <View>
            {expanded ? (
              <TouchableOpacity
                onPress={this.handleRoute.bind(this, child.label)}>
                <View style={[styles.sidebarDesign]}>
                  <View style={styles.barIcon}>
                    {/* <Icon.FontAwesome
                            name={r.icon}
                            size={20}
                            color={Color.gray}
                          /> */}
                  </View>
                  <View style={styles.barLabel}>
                    <Text style={[styles.labelStyle]}>
                      {child.label.toUpperCase()}
                    </Text>
                  </View>
                  <View style={styles.barIcon}>{/* <Text>icon</Text> */}</View>
                </View>
              </TouchableOpacity>
            ) : null}
          </View>
        ))}
      </View>
    );
  }
}

});

export default CollapseMenu;
 

И используйте этот компонент, передавая данные, такие как:

  <CollapseMenu item={data}/>
 

Комментарии:

1. какую react navigation версию вы используете?

2. @NileshPatel v5

3. ОК. можете ли вы поделиться кодом родительского компонента?

4. проблема в том, что вы используете class component ‘ CollapseMenu .

5. @NileshPatel не могли бы вы объяснить мне вкратце?

Ответ №1:

С react-navigation v5 единственным api, по которому мы должны перемещаться из вложенных дочерних / не-компонентов маршрута, является useNavigate hook, который может использоваться только в функциональных компонентах.

Согласно документам, обходной путь для использования в компоненте класса заключается в создании компонента функции-оболочки.

 import React, {useState, useEffect} from 'react';
import {
  View,
  StyleSheet,
  Text,
  LayoutAnimation,
  TouchableOpacity,
} from 'react-native';

import Font from '../constant/fonts';
import Color from '../constant/colors';
import fontF from '../styles/fontfamily';
import Icon from '../styles/icons';

import {heightToDp, widthToDp} from '../constant/utils';
import Size from '../constant/sizes';
import Card from './Cards/card';
import {Divider} from 'react-native-elements';
class CollapseMenu extends React.Component {
  componentDidMount() {
    console.log('navigation', this.props);
  }

  constructor(props) {
    super(props);

    this.state = {
      expanded: false,
    };
    this.handleCollapse = this.handleCollapse.bind(this);
  }

  handleCollapse() {
    const {expanded} = this.state;
    this.setState({expanded: !expanded});
  }
  handleRoute(label) {
    console.log(this.props);
    this.props.navigation.navigate(label);
  }

  render() {
    const {expanded} = this.state;
    return (
      <View>
        <TouchableOpacity onPress={this.handleCollapse}>
          <View style={styles.mainContainer}>
            <View style={[styles.sidebarDesign]}>
              <View style={styles.barIcon}>
                <Icon.SimpleLineIcons name={this.props.item.icon} size={20} />
              </View>
              <View style={styles.barLabel}>
                <Text style={[styles.labelStyle]}>
                  {this.props.item.title.toUpperCase()}
                </Text>
              </View>
              <View style={styles.barIcon}>
                <Icon.SimpleLineIcons
                  name={expanded ? 'arrow-up' : 'arrow-down'}
                  size={20}
                  color={Color.grayDark}
                />
              </View>
            </View>
          </View>
        </TouchableOpacity>

        {this.props.item.subarr.map((child, j) => (
          <View>
            {expanded ? (
              <TouchableOpacity
                onPress={this.handleRoute.bind(this, child.label)}>
                <View style={[styles.sidebarDesign]}>
                  <View style={styles.barIcon}>
                    {/* <Icon.FontAwesome
                            name={r.icon}
                            size={20}
                            color={Color.gray}
                          /> */}
                  </View>
                  <View style={styles.barLabel}>
                    <Text style={[styles.labelStyle]}>
                      {child.label.toUpperCase()}
                    </Text>
                  </View>
                  <View style={styles.barIcon}>{/* <Text>icon</Text> */}</View>
                </View>
              </TouchableOpacity>
            ) : null}
          </View>
        ))}
      </View>
    );
  }
}

});

// Wrap and export 
function CollapseMenuWrapper(props) {
  const navigation = useNavigation();

  return <CollapseMenu {...props} navigation={navigation} />;
}
export default CollapseMenuWrapper;