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
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.
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;
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>
);
}
}