如何动态创建 Stack.Screen ? - 我无法导航到动态创建的屏幕

How to dynamically create Stack.Screen ? - I can't navigate to dynamically created Screens

我有一个对象,我正在尝试循环以动态创建屏幕。我有一个抽屉,其中包含一个项目列表,每个项目都有一个 onPress 函数来导航到那些动态创建的屏幕。但是,当我按下抽屉中的某个项目时,没有任何反应。我想知道我的循环是否不正确,但我无法确定原因;如果我 console.log,我可以看到创建正确屏幕所需的所有适当信息。如果我手动创建屏幕,onPress 会导航到相应的屏幕

这是App.js

const drawerItemsMain = [
  {
    key: 'Pastry',
    title: 'Pastry',
    routes: [
      {nav: 'MainDrawer', routeName: "LemonBar", title: 'LemonBar'},
    ],
  },
]

const MainDrawerNavigation = () => {
    return(
        <Drawer.Navigator drawerContent={(props) => <CustomDrawerContent drawerItems={drawerItemsMain} {...props}/>}>
            <Drawer.Screen name="Home" component={HomeScreen} />
            {
                drawerItemsMain.map((item) => {
                    item.routes.map((route) => {
                        console.log(route.title)
                        return (
                            <Drawer.Screen 
                                key={route.title}
                                name={route.title}
                                component={route.routeName}
                                options={{ title: route.title }}
                            />
                        )
                    })
                })
            }
            //<Drawer.Screen name="LemonBar" component={LemonBar} /> //this works
        </Drawer.Navigator>
    )
}

const App = () => {
  return (
    <NavigationContainer>
        <Stack.Navigator screenOptions={{headerShown: false}}>
            <Stack.Screen name="MainDrawer" component={MainDrawerNavigation} />
        </Stack.Navigator>
    </NavigationContainer>
  );
}

提前感谢您的帮助

您绝对可以动态创建屏幕,但是您有两个 array.map 函数,一个 returns 屏幕,以及一个 returns 没有任何内容。

尝试

{drawerItemsMain.reduce((res, group) => [
   ...res, 
   ...(group.routes.map((route) => (
     <Drawer.Screen 
       key={route.title}
       name={route.title}
       component={route.routeName}
       options={{ title: route.title }}
     />
   ))
  ],
  [], // reducer inital state
)}

(在 .map 中嵌套 .map 会返回一个屏幕数组。在这里使用 .reduce 以获得平面屏幕数组)

我认为您必须为 onPress 传递适当屏幕的 ID 或 link。

您忘记添加 return 语句。以下解决了这个问题。

<Drawer.Navigator drawerItems={drawerItemsMain}>
    <Drawer.Screen name="Home" component={HomeScreen} />
            {
                drawerItemsMain.map((item) => {
                    return item.routes.map((route) => {
                        console.log(route.title)
                        return (
                            <Drawer.Screen 
                                key={route.title}
                                name={route.title}
                                component={route.routeName}
                                options={{ title: route.title }}
                            />
                        )
                    })
                })
            }
        </Drawer.Navigator>

另请注意,导航框架不会以 JSX 组件的方式创建实际的屏幕组件。因此,您的项目中必须存在一个名为 LemonBar 的 JSX 组件,它也被导入到您的抽屉初始化文件中。

从这个意义上讲,没有“根据组件动态创建屏幕”。如果组件已导入并存在于您的项目中,那么您可以使用上面的代码片段将它们作为屏幕添加到抽屉导航器中。