错误:没有为键添加杂货项定义路由。必须是以下之一:"屏幕"堆栈操作



我遵循这个SO答案-我只是试图在导航时重置堆栈,以便在导航离开时卸载我的组件,因为我需要componentDidMount在导航到它时激发它。

我想从这个开始:

const navigateAction = NavigationActions.navigate({
routeName: route
})
props.navigation.dispatch(navigateAction)

到此:

const resetAction = StackActions.reset({
index: 0,
actions: [NavigationActions.navigate({ routeName: route })],
})
props.navigation.dispatch(resetAction)

但当我这样做的时候,我会得到这个错误:

错误:没有为关键字Add Grocery Item定义路由。必须是一个的:"屏幕"堆叠

这是上面代码中的完整功能:

navigateToScreen = (route, props, headingKey: string) => () => {
if (this.props.navigationProps.activeItemKey !== headingKey) {
this.setState({ activeSections: [] })
}
// const navigateAction = NavigationActions.navigate({
//   routeName: route
// })

const resetAction = StackActions.reset({
index: 0,
actions: [NavigationActions.navigate({ routeName: route })],
})
props.navigation.dispatch(resetAction)
}

以下是我的导航路线:

export const AddMenuIcon = ({ navigate }: NavigateType) => (
<View>
<Icon
name="plus"
size={25}
color="#FFF"
onPress={() => navigate('DrawerOpen')}
/>
</View>
)
export const SearchMenuIcon = ({ navigate }: NavigateType) => (
<Icon
name="search"
size={25}
color="#FFF"
onPress={() => navigate('DrawerOpen')}
/>
)
export const Stack = {
Login: {
screen: Login
},
Search: {
screen: Search
},
AddGroceryItem: {
screen: AddGroceryItem
},
AddGroceryStore: {
screen: AddGroceryStore
}
}
export const DrawerRoutes = {
Login: {
name: 'Login',
screen: Login
},
'Find Vegan': {
name: 'Search',
screen: createStackNavigator(Stack.Search, {
headerMode: 'none'
}),
navigationOptions: ({ navigation }: NavigationType) => ({
drawerIcon: SearchMenuIcon(navigation)
})
},
'Add Grocery Item': {
name: 'Add',
screen: createStackNavigator(Stack.AddGroceryItem, {
headerMode: 'none'
}),
navigationOptions: ({ navigation }: NavigationType) => ({
drawerIcon: AddMenuIcon(navigation)
})
},
'Add Grocery Store': {
name: 'AddGroceryStore',
screen: createStackNavigator(Stack.AddGroceryStore, {
headerMode: 'none'
}),
navigationOptions: ({ navigation }: NavigationType) => ({
drawerIcon: AddMenuIcon(navigation)
})
}
}
export const sections = [
{
mainHeading: 'Login',
navigationPath: 'Login',
icon: 'user-circle'
},
{
mainHeading: 'Find Vegan',
navigationPath: 'Find Vegan',
icon: 'search'
},
{
mainHeading: 'Add Vegan',
subOptions: [
{
secondaryHeading: 'Grocery Items',
mainHeading: 'Add Vegan',
secondaryHeadingKey: 'Add Grocery Item',
navigationPath: 'Add Grocery Item',
icon: { name: 'shopping-basket', color: Colors.white }
},
{
secondaryHeading: 'Grocery Stores',
mainHeading: 'Add Vegan',
secondaryHeadingKey: 'Add Grocery Itemx',
navigationPath: 'Add Grocery Store',
icon: { name: 'shopping-cart', color: Colors.white }
},
{
secondaryHeading: 'Restaurant Meals',
mainHeading: 'Add Vegan',
secondaryHeadingKey: 'Add Grocery Itemx',
navigationPath: 'Add Grocery Item',
icon: { name: 'utensils', color: Colors.white }
},
{
secondaryHeading: 'Restaurants',
mainHeading: 'Add Vegan',
secondaryHeadingKey: 'Add Grocery Itemx',
navigationPath: 'Add Grocery Item',
icon: { name: 'store-alt', color: Colors.white }
},
{
secondaryHeading: 'Events',
mainHeading: 'Add Vegan',
secondaryHeadingKey: 'Add Grocery Itemx',
navigationPath: 'Add Grocery Item',
icon: { name: 'calendar-alt', color: Colors.white }
},
{
secondaryHeading: 'Fashion',
mainHeading: 'Add Vegan',
secondaryHeadingKey: 'Add Grocery Itemx',
navigationPath: 'Add Grocery Item',
icon: { name: 'tshirt', color: Colors.white }
}
],
icon: 'plus-circle'
}
]

这是我的完整菜单组件,它有导航菜单

class AccordionView extends React.Component<AccordianProps, AccordianState> {
state = {
activeSections: [],
sections: Data.sections
}
getParentLabelStyle = (mainHeading: string) => {
if (this.props.navigationProps.activeItemKey === mainHeading) {
return { ...Typography.whiteLabel, color: Colors.green_lite_2 }
}
const sectionFromSubOption = this.state.sections.find(
(x) =>
x.subOptions &&
x.subOptions.find(
(y) =>
y.secondaryHeadingKey === this.props.navigationProps.activeItemKey
)
)
if (
sectionFromSubOption &&
sectionFromSubOption.mainHeading === mainHeading
) {
return { ...Typography.whiteLabel, color: Colors.green_lite_2 }
} else {
return Typography.whiteLabel
}
}
getParentIconColor = (mainHeading: string) => {
if (this.props.navigationProps.activeItemKey === mainHeading) {
return Colors.green_lite_2
}
const sectionFromSubOption = this.state.sections.find(
(x) =>
x.subOptions &&
x.subOptions.find(
(y) =>
y.secondaryHeadingKey === this.props.navigationProps.activeItemKey
)
)
if (
sectionFromSubOption &&
sectionFromSubOption.mainHeading === mainHeading
) {
return Colors.green_lite_2
} else {
return Colors.white
}
}
getLabelStyle = (headingKey: string) => {
if (this.props.navigationProps.activeItemKey === headingKey) {
return { ...Typography.whiteLabel, color: Colors.green_lite_2 }
} else {
return Typography.whiteLabel
}
}
getIconColor = (headingKey: string): string => {
if (this.props.navigationProps.activeItemKey === headingKey) {
return Colors.green_lite_2
} else {
return Colors.white
}
}
updateSections = (activeSections) => {
this.setState({ activeSections })
}
navigateToScreen = (route, props, headingKey: string) => () => {
if (this.props.navigationProps.activeItemKey !== headingKey) {
this.setState({ activeSections: [] })
}
// const navigateAction = NavigationActions.navigate({
//   routeName: route
// })

const resetAction = StackActions.reset({
index: 0,
actions: [NavigationActions.navigate({ routeName: route })],
})
props.navigation.dispatch(resetAction)
}
renderSectionTitle = () => {
return <View />
}
renderHeader = (section, userName?: string) => {
return (
<View>
{section.navigationPath && (
<TouchableOpacity
onPress={this.navigateToScreen(
section.navigationPath,
this.props.navigationProps
)}>
<View style={styles.subMenuItemContainer}>
<AwesomeIcon
style={styles.icon}
name={section.icon}
light
size={25}
color={this.getParentIconColor(section.mainHeading)}
/>
<Text
style={{ ...this.getParentLabelStyle(section.mainHeading) }}>
{userName ? userName : section.mainHeading}
</Text>
</View>
</TouchableOpacity>
)}
{section.subOptions && (
<View style={styles.subMenuItemContainer}>
<AwesomeIcon
style={styles.icon}
name={section.icon}
size={25}
light
color={this.getParentIconColor(section.mainHeading)}
/>
<Text style={{ ...this.getParentLabelStyle(section.mainHeading) }}>
{section.mainHeading}
</Text>
</View>
)}
</View>
)
}
renderContent = (section) => {
return (
section.subOptions &&
section.subOptions.map(
(item) =>
item.secondaryHeading === 'Grocery Items' ? (
<TouchableOpacity
onPress={this.navigateToScreen(
item.navigationPath,
this.props.navigationProps,
item.secondaryHeadingKey
)}>
<View style={{...styles.parentMenuItemContainer, marginLeft: -20}}>
<AwesomeIcon
style={styles.icon}
size={25}
light
name={item.icon.name}
color={this.getIconColor(item.secondaryHeadingKey)}
/>
<Text
style={{ ...this.getLabelStyle(item.secondaryHeadingKey) }}>
{item.secondaryHeading}
</Text>
</View>
</TouchableOpacity>
) : (
<View style={{...styles.parentMenuItemContainer, marginLeft: -20}}>
<AwesomeIcon
style={styles.icon}
size={25}
light
name={item.icon.name}
color={'#969696'}
/>
<Text
style={{ ...this.getLabelStyle(item.secondaryHeadingKey), color: '#969696' }}>
{item.secondaryHeading}
</Text>
<Text
style={{ ...this.getLabelStyle(item.secondaryHeadingKey), fontSize: 12, paddingLeft: 0, color: 'red' }}>
(coming soon)
</Text>
</View>
)
)
)
}
render() {
return (
<Accordion
sections={this.state.sections}
activeSections={this.state.activeSections}
renderSectionTitle={this.renderSectionTitle}
renderHeader={(section) => {
let userName
if (section.mainHeading === 'Login') {
const loginItem = this.props?.navigationProps?.items?.find(
(x) => x.key === 'Login'
)
userName = loginItem?.params?.userFirstName
}
return this.renderHeader(section, userName)
}}
renderContent={this.renderContent}
onChange={this.updateSections}
/>
)
}
}
export class CustomDrawerContentComponent extends React.Component<
AccordianProps,
AccordianState
> {
state = {}
render() {
return (
<SafeAreaView style={styles.menuContainer}>
<View style={styles.vepoImageContainer}>
<Image
style={styles.vepoImage}
square
source={require('src/images/logo_v_white.png')}
/>
</View>
<Text style={styles.mottoText}>Find Every Vegan Thing!</Text>
<View style={styles.accordianContainer}>
<AccordionView navigationProps={this.props} />
</View>
<AlertModalComponent
yesClicked={() => {
updateAlertModalIsOpen(false)
}}
/>
</SafeAreaView>
)
}
}
const { width, height } = Dimensions.get('screen')
let Menu = createStackNavigator(
{
Drawer: {
name: 'Drawer',
screen: createDrawerNavigator(Data.DrawerRoutes, {
initialRouteName: 'Login',
drawerPosition: 'left',
drawerWidth: Math.min(height, width),
contentComponent: CustomDrawerContentComponent,
contentOptions: {
activeTintColor: '#27a562',
inactiveTintColor: 'white',
activeBackgroundColor: '#3a3a3a'
}
})
}
},
{
headerMode: 'none',
initialRouteName: 'Drawer'
}
)
const menuItemContainer = {
display: 'flex',
flexDirection: 'row',
height: 50,
alignItems: 'center',
borderBottomWidth: Borders.thinBorder,
borderBottomColor: Colors.grey_dk_2
}
const styles = {
vepoImage: {
marginLeft: Spacing.sm_4,
marginBottom: Spacing.none,
marginTop: Spacing.md_2,
width: 120,
height: Distances.FormElementHeights.Double,
resizeMode: 'contain'
},
accordianContainer: {
borderTopWidth: Borders.thinBorder,
borderTopColor: Colors.grey_dk_2
},
mottoText: { ...Typography.whiteLabel, marginBottom: Spacing.md_4 },
vepoImageContainer: {
marginBottom: Spacing.md_4
},
menuContainer: {
flex: 1,
backgroundColor: Colors.grey_dk_3,
color: Colors.white
},
icon: {
marginLeft: Spacing.md_4,
width: 30
},
subMenuItemContainer: menuItemContainer,
parentMenuItemContainer: {
...menuItemContainer,
paddingLeft: Spacing.lg_7
}
}
// $FlowFixMe
Menu = createAppContainer(Menu)
export default Menu

如何修复此错误?

看起来您正在导航到每个部分的navigationPath属性,在本例中,您将其定义为Add Grocery Item,而您试图导航到的实际路径是AddGroceryItem

最新更新