junep
junep

Reputation: 2164

make dynamic tab on createMaterialTopTabNavigator of react-navigation

I'm making the top tab navigator using createMaterialTopTabNavigator of react-navigation. The problem I faced is that the tabs have to decide by the response data of API request. For example, I call an API to request the football team list, receive the list and then set the tabs of the MaterialTopTabNvigator.

I already make the label of the navigator using the component like following :

class TabBarLabel extends React.Component {
  constructor(props) {
    super(props);
  }
  render() {
    return this.props.focused ? (
      <View style={lstyles.container_focused}>
        <Text style={lstyles.label_focused}>{this.props.name}</Text>
      </View>
    ) : (
      <View style={lstyles.container_blur}>
        <Text style={lstyles.label_blur}>{this.props.name}</Text>
      </View>
    );
  }
}

const FootballTeamNavigator = createMaterialTopTabNavigator(
  {
    teamA : {
      screen: AScreenComponent,
      navigationOptions: () => {
        return {
          title: 'teamA',
          tabBarLabel({focused}) {
            return <TabBarLabel focused={focused} name="teamA" />;
          }
        };
      }
    }
  },
  {
    initialRouteName: teamA,
    swipeEnabled: false,
    timingConfig: {
      duration: 1000,
    },
    tabBarOptions: {
      scrollEnabled: true,
      ...styles,
    },
  },
);

What I want to do is like :

let teamList = {};

apiForGetFootballTeamList().then(response => {
  for (const team of response.data.list) {
    tempList[team.name] = team;
  }
});

createMaterialTopTabNavigator(
  {
    ...teamList
  },
  {
    initialRouteName: ...,
    ...
  }
);

But I don't know how can I update the tabs using data, like component. (component has state and if we update the state, the component is updated)

Is there any way for it?

Upvotes: 3

Views: 5209

Answers (2)

linkedby
linkedby

Reputation: 168

Got to a couple of different threads trying to do this (this one among others). Did not manage to find a solution, but in the end it ended up being rather easy.

<Tab.Navigator>
            {villages.map(village => (
                <Tab.Screen
                    key={village.villageId}
                    name={village.name}
                    component={ResourceFieldScreen}
                    initialParams={{ village: village }}
                />
            ))}
</Tab.Navigator>

At the top, before the function itself I have:

const Tab = createMaterialTopTabNavigator();

In this case screens are created based on how many counts of village there are in villages. Then a prop of village is sent to the component that is supposed to render it all ResourceFieldScreen. Which makes it possible to show whatever is included in villages, on that screen.

Code for that part:

function ResourceFieldScreen({ route }) {
  const village = route.params.village;

Upvotes: 2

satya164
satya164

Reputation: 10145

Current versions of React Navigation don't support dynamic configuration. You need to use React navigation 5 for that https://blog.expo.io/announcing-react-navigation-5-0-bd9e5d45569e

Upvotes: 2

Related Questions