React Native - Creating Navigator dynamically with React Navigation

后端 未结 3 834
不知归路
不知归路 2021-02-06 06:37

I am building a mobile application with React Native and I am using React Navigation to build a navigator inside my application. React navigation provided me a good way to handl

相关标签:
3条回答
  • 2021-02-06 07:24

    It's been a while this q was posted but if there are still some people looking at this. I'd rather using react-native-navigation instead this library.

    0 讨论(0)
  • 2021-02-06 07:31

    Here I would like to post a method for creating tab bar according to the data we fetched from some API etc programmatically.

    Here we fetch the data from API in this example, this code from the top level component :

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

    This code snippet is from creator of the tab bar dynamically :

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

    As last , I will show you customized tab navigation bar I built :

    const TabMenuItems = ({props}) => {
    
        const { activeTintColor, tab, tabbar, tabText, inactiveTintColor } = styles;
        const { index } = props.navigation.state;
        return(
            <View>
            <ScrollView contentContainerStyle={{ flex : 1 }} horizontal showsHorizontalScrollIndicator={false} style={{backgroundColor : '#FFAEB9'}}>
            {
                props.navigation.state.routes.length ? (
                    props.navigation.state.routes.map((route,number)=>{
                        const focused = ( index === number ) ? '#1874CD' : '#FF6A6A';
                        const tintColor = focused ? activeTintColor : inactiveTintColor;
                        return (
                            <TouchableWithoutFeedback
                                key={route.key}
                                onPress={() => {
                                    props.jumpToIndex(number)
                                }}
                                delayPressIn={0}
                                >
                                <View style={{marginLeft : 20, marginTop : height / 40, shadowOpacity : 25, alignSelf : 'flex-start' }}>
                                    <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'}}>
                                    {props.getLabel({route, number})}
                                    </Text>
                                </View>
                            </TouchableWithoutFeedback>
                        )
                    })
                ) : null
            }
        </ScrollView>
        </View>
        )
    }
    
    export default TabMenuItems;

    0 讨论(0)
  • 2021-02-06 07:44

    Your TabStack file:

    const CATEGORIES = {
      "Food": { screen: FoodStack },
      // ...
    }
    
    export default (screenNames) => {
      const screens = screenNames.reduce((total, name) => ({...total, [name]: CATEGORIES[name]}), {})
      const TabStack = TabNavigator(screens,
        {
            tabBarComponent : props => <CustomTabItems props={props}/>,
            tabBarPosition: 'top',
            animationEnabled : true,
            initialRouteName : 'Food',
            swipeEnabled: true,
            tabBarOptions : {
    
                scrollEnabled : true
            }
      })
      return TabStack
    }
    

    Your Root file:

    import getTabStack from './TabStack'
    
    
    class Root extends Component {
    
        state = {
          categoriesNames: null
        }
    
        componentWillMount() {
          // assuming result is ["Food", "Drink", ... ]
          Api.fetchCategories().then((result) => {
            this.setState({ categoriesNames: result })
          })
        }
    
        render() {
          const { categoriesNames } = this.state
          if (!categoriesNames) {
            return <SplashScreen />
          }
          const TabStack = getTabStack(categoriesNames)
          return (
            <Provider store={store} >
              <TabStack />
            </Provider>
          );
        }
      }
    
    0 讨论(0)
提交回复
热议问题