#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;