React Native - 使用React Navigation动态创建Navigator

oze*_*lan 7 tabnavigator react-native react-navigation

我正在使用React Native构建移动应用程序,我正在使用React Navigation在我的应用程序中构建导航器.React导航为我提供了一个很好的方法来处理抽屉内的嵌套Tab栏,它也在Stack Navigator中.

问题是我需要指定组件,以便我可以将它们提供到Tab栏中.让我们说我们必须从API中获取一些类别,我们不知道数据中有多少类别.此外,我无法弄清楚即使我尝试在启动时获取数据,导航器和redux配置也会在启动时发生,这意味着应用程序必须知道这些选项卡导航器中的组件.我无法弄清楚即使我从API获取数据,我如何创建多个组件并停止应用程序配置.

下面的代码,演示了我如何实现标签栏.此代码在index.js中有效,因为正如我之前提到的,应用程序必须知道Navigator中的组件.

const TabStack = TabNavigator({
    Food: { screen: FoodStack},
    Drink : { screen: DrinkStack },
    HealthCare : { screen: SnackProducts },
    Snacks: { screen: SnackStack },
},
    {
        tabBarComponent : props => <CustomTabItems props={props}/>,
        tabBarPosition: 'top',
        animationEnabled : true,
        initialRouteName : 'Food',
        swipeEnabled: true,
        tabBarOptions : {
 
            scrollEnabled : true
        }
})
Run Code Online (Sandbox Code Playgroud)

谢谢

这里是根代码

import { AppRegistry } from 'react-native';
import React from 'react';

import { Text, Image, ScrollView, View, List, ListItem, TouchableWithoutFeedback } from 'react-native';
import { Icon, Avatar } from 'react-native-elements';

import { Provider, connect } from 'react-redux'
import thunkMiddleware from 'redux-thunk'
import { createStore, applyMiddleware, combineReducers } from 'redux';
import {
    addNavigationHelpers, StackNavigator,
    DrawerNavigator,
    DrawerItems,
    TabNavigator,
    TabView,
    TabBarTop,
    NavigationActions
} from 'react-navigation';

// importing starting screen 

import StartingContainer from './src/containers/StartingScreen/StartingContainer';

// Menu Containers
import MenuCredentials from './src/containers/MenuCredentials';

// Containers
import LoginContainer from './src/containers/LoginContainer';
import PhoneNumberValidation from './src/containers/SubLoginContainers/PhoneNumberValidation';
import MainOrderContainer from './src/containers/OrderContainers/MainOrderContainer';
import MainCartContainer from './src/containers/CartContainers/MainCartContainer';

// Components 
// Login Components
import SMSLogin from './src/containers/SubLoginContainers/SMSLogin';

// Profil Components
import Profil from './src/components/ProfileComponents/Profile';
import AdressComponent from './src/components/ProfileComponents/AdressComponent';
import SettingsComponent from './src/components/ProfileComponents/SettingsComponent';
import creditCardComponent from './src/components/ProfileComponents/creditCardComponent';
// Reducers
import initialReducer from './src/reducers/initialReducer';
import cartReducer from './src/reducers/cartReducer';
import starterReducer from './src/reducers/starterReducer';

// import tab bar containers

import FoodProducts from './src/containers/TabBarContainers/FoodProducts';
import HealthProducts from './src/containers/TabBarContainers/HealthProducts';
import SnackProducts from './src/containers/TabBarContainers/SnackProducts';

// Building Navigation
import MenuItem from './src/containers/MenuItemContainer/MenuItem';
import CustomTabItems from './src/containers/CustomTabItems';
import CustomSubTabItems from './src/containers/CustomSubTabItems';

import DrawerButton from './src/containers/DrawerButton';

// Tab Bar Navigation
const ChocolateStack = TabNavigator({
    Tadelle: { screen: MenuItem},
    Milka: { screen: MenuItem},
},
    {
        tabBarComponent : props => <CustomTabItems props={props}/>,
        tabBarPosition: 'top',
        animationEnabled : true,
        initialRouteName : 'Tadelle',
        swipeEnabled: true,
        tabBarOptions: {
            scrollEnabled: true
        },

})
const SnackStack = TabNavigator({
    Çikolatalar: { screen: MenuItem},
    Gofretler: { screen: MenuItem},
    Krakerler: { screen: MenuItem},
    Bisküviler: { screen: MenuItem},
    Kuruyemi?ler: { screen: MenuItem},
},
    {
        tabBarComponent : props => <CustomSubTabItems props={props}/>,
        tabBarPosition: 'top',
        animationEnabled : true,
        initialRouteName : 'Çikolatalar',
        swipeEnabled: true,
        tabBarOptions : {
            scrollEnabled : true
        }
})

const DrinkStack = TabNavigator({
    'Gazl? ?çecekler': { screen: MenuItem},
    'So?uk Çaylar': { screen: MenuItem},
    'Alkol': { screen: MenuItem},
    'Süt Ürünleri': { screen: MenuItem},
    'Spor ?çecekleri': { screen: MenuItem},
},
    {
        tabBarComponent : props => <CustomSubTabItems props={props}/>,
        tabBarPosition: 'top',
        animationEnabled : true,
        initialRouteName : 'Alkol',
        swipeEnabled: true,
        tabBarOptions : {
            scrollEnabled : true
        }
})

const FoodStack = TabNavigator({
    Sandviç : { screen: MenuItem},
    Çorba: { screen: MenuItem},
},
    {
        tabBarComponent : props => <CustomSubTabItems props={props}/>,
        tabBarPosition: 'top',
        animationEnabled : true,
        initialRouteName : 'Sandviç',
        swipeEnabled: true,
        tabBarOptions : {
            scrollEnabled : true
        }
})


const TabStack = TabNavigator({
    Food: { screen: FoodStack},
    Drink : { screen: DrinkStack },
    Health : { screen: SnackProducts },
    Snacks: { screen: SnackStack },
},
    {
        tabBarComponent : props => <CustomTabItems props={props}/>,
        tabBarPosition: 'top',
        animationEnabled : true,
        initialRouteName : 'Food',
        swipeEnabled: true,
        tabBarOptions : {
            tabStyle : {
                width : 250
            },
            scrollEnabled : true
        }
})




// cart navigation will be drawernavigator and drawerItems will be custom !!
const CartNavigation = StackNavigator({
    Cart: {
        screen: MainCartContainer,
    }
},
    {
        headerMode: 'float',
        navigationOptions: ({ navigation }) => ({
            title: 'Sepet',
            headerLeft: <Icon
                name='arrow-back'
                color='#517fa4'
                onPress={() => navigation.navigate('drawerStack')}
            />,
            headerRight:
            <Icon
                name='payment'
                color='#517fa4'
                onPress={() => navigation.navigate('drawerStack')}
            />
        })

    }
)
const DrawerStack = DrawerNavigator({
    Sipari?: { screen: TabStack },
    Profil: { 
        screen: Profil ,
        navigationOptions : ({ navigation }) => ({
            title : 'Profilim',
        })
    },
    Adreslerim: {
        screen: AdressComponent,
        navigationOptions: ({ navigation }) => ({
            title: 'Teslimat Adreslerim'
        })
    },
    Ayarlar: { screen: SettingsComponent }
},
    {
        drawerPosition: 'left',
        headerMode : 'none',
        navigationOptions: ({ navigation }) => ({
            headerStyle: { backgroundColor: '#87CEFA' },
            headerRight: <Icon
            name='shopping-cart'
            color='#517fa4'
            onPress={() => navigation.navigate('cartStack')}
            />,
        }),
        contentOptions: {
            inactiveTintColor: 'white',
            activeTintColor: 'purple',
            style: {
                marginTop: 80,
                marginLeft: 25,
            }
        },
        contentComponent: props => <MenuCredentials {...props} />
})

const DrawerNavigation = StackNavigator({
    DrawerStack: {
        screen: DrawerStack
    }},
   {
       style : {
           leftDrawerWidth : 40
       },
       index : 0,
       navigationOptions : ({ navigation }) => ({
            headerStyle: { backgroundColor: '#87CEFA' },
            gesturesEnabled : false,
            headerRight : <Icon
            name='shopping-cart'
            color='#517fa4'
            onPress={() => navigation.navigate('cartStack')}
            />,
            headerLeft: <Icon
            name='menu'
            color='#517fa4'
            onPress={() => {
                console.log(navigation.state.routes[0]);
                navigation.navigate({
                    key : null,
                    index : 0,
                    action : [
                        navigation.navigate('DrawerToggle')
                    ]
                })
            }}
            />
       }),
       initialRouteParams : {
           name : 'Welcome'
       }
   } 
)

const LoginStack = StackNavigator({
    Login: {
        screen: LoginContainer,
        navigationOptions: ({ navigation }) => ({
            title: ' G?ZL? UYGULAMA ! '
        })
    },
    Ss: {
        screen: SMSLogin,
        navigationOptions: ({ navigation }) => ({
            title: ' SMS ONAYI '
        })
    },
    PhoneNumberValidation: {
        screen: PhoneNumberValidation,
        navigationOptions: ({ navigation }) => ({
            title: 'Kaydolma'
        })
    },
    },{
        headerMode : 'none',
        initialRouteName : 'Login'
})

// IMPORTANT NOTE ***!!!
// CARRY drawerStack to the PrimaryNavigator !!
// CHANGE LoginContainer so that it will navigate to the drawerStack
// NOT FROM ACTION BUT FROM COMPONENT INSIDE COMPONENTWILLUPDATE
// BY CHANGING isAuth variable in initialReducer !!

const PrimaryNavigator = StackNavigator({
    loginStack: {
        screen: LoginStack
    },
    cartStack: {
        screen: CartNavigation
    },
    drawerStack: {
        screen:  DrawerNavigation
    },
    starter : {
        screen : StartingContainer
    }
},
    {
        headerMode: 'none',
        title: 'Main',
        initialRouteName : 'starter'
    }
)

const navReducer = (state, action) => {
    const nextState = PrimaryNavigator.router.getStateForAction(action, state);
    // Simply return the original `state` if `nextState` is null or undefined.
    return nextState || state;
};

// combining Reducers
const AppReducer = combineReducers({
    initialR: initialReducer,
    cartR: cartReducer,
    starterR : starterReducer,
    nav: navReducer
})

// Creating redux store

const store = createStore(
    AppReducer,
    applyMiddleware(thunkMiddleware)
)

// Navigation initilizator to App
class App extends React.Component {
    render() {
        return (
            <PrimaryNavigator navigation={addNavigationHelpers({
                dispatch: this.props.dispatch,
                state: this.props.nav
            })}
            />
        )
    }
}
const mapStateToProps = (state) => ({
    nav: state.nav
})

const AppWithNavigationState = connect(mapStateToProps)(App);

class brilliantApp extends React.Component{
    render(){
        return(
            <Provider store={store}>
            < AppWithNavigationState />
        </Provider>
        )        
    }
}

AppRegistry.registerComponent('brilliantApp', () => brilliantApp);
Run Code Online (Sandbox Code Playgroud)

oze*_*lan 3

在这里,我想发布一种根据我们以编程方式从某些 API 等获取的数据创建标签栏的方法。

\n\n

在此示例中,我们从 API 获取数据,此代码来自顶级组件:

\n\n

\r\n
\r\n
renderShopTab() {\r\n        const { client } = this.props;\r\n        try {\r\n            const { categories } = client.readQuery({\r\n                query: gql`\r\n                {\r\n                    categories{\r\n                        id\r\n                        name\r\n                        products{\r\n                            id\r\n                            name\r\n                            price\r\n                            quantity\r\n                        }\r\n                    }\r\n                }`\r\n            })\r\n\r\n            console.log("Categories  :" + categories);\r\n\r\n            return (\r\n                <ShopCreator categories={categories} />\r\n            )\r\n\r\n        } catch (error) {\r\n            console.log("Error occured creating the categories due to the : " + error);\r\n\r\n            return (\r\n                <View>\r\n                    <Text>\r\n                        Loading...\r\n                    </Text>\r\n                </View>\r\n            )\r\n\r\n        }\r\n\r\n    }
Run Code Online (Sandbox Code Playgroud)\r\n
\r\n
\r\n

\n\n

此代码片段来自动态标签栏的创建者:

\n\n

\r\n
\r\n
export const ShopCreator = ({ categories }) => {\r\n\r\n    // This script will create a TabNavigator for categories and StackNavigators for each member of the categories !\r\n\r\n    let categoryStack = {};\r\n\r\n    let routes = {};\r\n\r\n\r\n    categories.forEach((category) => {\r\n\r\n        if (category.products.length > 0) {\r\n\r\n            const { catname } = category.name;\r\n\r\n            if (category.name != undefined) {\r\n\r\n                routes[category.name] = {\r\n                    screen: StackNavigator({\r\n                        \'isim\': {\r\n                            screen: ProductPage\r\n                        }\r\n                    },{\r\n                        headerMode : \'none\',\r\n                        initialRouteParams : {\r\n                            categoryName : category.name,\r\n                            products : category.products\r\n                        }\r\n                    })\r\n                }\r\n            }\r\n            \r\n        } else {\r\n\r\n            console.log("This category has no products !");\r\n\r\n        }\r\n\r\n    })\r\n\r\n    console.log("OHA : " + JSON.stringify(routes));\r\n\r\n    const ShopCatTabNav = TabNavigator(routes, {\r\n        tabBarPosition: \'top\',\r\n        tabBarComponent: props => <TabMenuItems props={props} />\r\n    })\r\n\r\n    return <ShopCatTabNav />\r\n\r\n}
Run Code Online (Sandbox Code Playgroud)\r\n
\r\n
\r\n

\n\n

最后,我将向您展示我构建的自定义选项卡导航栏:

\n\n

\r\n
\r\n
const TabMenuItems = ({props}) => {\r\n\r\n    const { activeTintColor, tab, tabbar, tabText, inactiveTintColor } = styles;\r\n    const {\xc2\xa0index } = props.navigation.state;\r\n    return(\r\n        <View>\r\n        <ScrollView contentContainerStyle={{ flex : 1 }} horizontal showsHorizontalScrollIndicator={false} style={{backgroundColor : \'#FFAEB9\'}}>\r\n        {\r\n            props.navigation.state.routes.length ? (\r\n                props.navigation.state.routes.map((route,number)=>{\r\n                    const focused = ( index === number ) ? \'#1874CD\' : \'#FF6A6A\';\r\n                    const tintColor = focused ? activeTintColor : inactiveTintColor;\r\n                    return (\r\n                        <TouchableWithoutFeedback\r\n                            key={route.key}\r\n                            onPress={() => {\r\n                                props.jumpToIndex(number)\r\n                            }}\r\n                            delayPressIn={0}\r\n                            >\r\n                            <View style={{marginLeft : 20, marginTop : height / 40, shadowOpacity : 25, alignSelf : \'flex-start\' }}>\r\n                                <Text style={{borderRadius : 5, fontWeight : \'bold\', borderWidth :2, paddingTop : 5,color : \'white\', height : height/18, width : width/5,textAlign : \'center\', backgroundColor : focused, borderStyle: \'dashed\',borderColor : \'#CD2626\'}}>\r\n                                {props.getLabel({route, number})}\r\n                                </Text>\r\n                            </View>\r\n                        </TouchableWithoutFeedback>\r\n                    )\r\n                })\r\n            ) : null\r\n        }\r\n    </ScrollView>\r\n    </View>\r\n    )\r\n}\r\n\r\nexport default TabMenuItems;
Run Code Online (Sandbox Code Playgroud)\r\n
\r\n
\r\n

\n