Marius Stoica
Marius Stoica

Reputation: 3

Stacked React Navigators cause API to be called 2x when component is instantiated

I'm new to React Native and I have an app which uses a stack and tab navigator. The stack navigator is the child navigator of the tab navigator. The problem lies when a screen uses both of them, causing the useEffect in the component to be called twice. How can I fix this?

This is the App.js which contains the navigators:

const App = () => {
  return (
    <NavigationContainer>
      <TabNavigator />
    </NavigationContainer>
  );
};

const StackNavigator = () => {
  return (
    <Stack.Navigator>
      <Stack.Screen
        name="HomeScreen"
        component={HomeScreen}
        options={{ headerShown: false }}
      />
      <Stack.Screen
        name="Discover"
        component={DiscoverScreen}
        options={{ headerShown: false }}
      />
      <Stack.Screen
        name="MyGarden"
        component={MyGardenScreen}
        options={{ headerShown: false }}
      />
      <Stack.Screen
        name="Planty"
        component={PlantyScreen}
        options={{ headerShown: false }}
      />
      <Stack.Screen
        name="Specific"
        component={SpecificPlantScreen}
        options={{ headerShown: false }}
      />
    </Stack.Navigator>
  );
};

const TabNavigator = () => {
  return (
    <Tab.Navigator
      initialRouteName="Home"
      screenOptions={() => ({
        tabBarStyle: {
          height: 80,
          backgroundColor: "#232516",
          paddingBottom: 5,
        },
        headerShown: false,
        tabBarActiveTintColor: "white",
        tabBarInactiveTintColor: "gray",
      })}
    >
      <Tab.Screen
        name="Home"
        component={StackNavigator}
        options={{
          tabBarIcon: ({ focused }) => (
            <FontAwesome
              style={focused ? styles.focusedNavButtonBackground : {}}
              name="home"
              size={35}
              color={focused ? "black" : "white"}
            />
          ),
        }}
      />
      <Tab.Screen
        name="Discover"
        component={DiscoverScreen}
        options={{
          tabBarIcon: ({ focused }) => (
            <FontAwesome
              style={focused ? styles.focusedNavButtonBackground : {}}
              name="search"
              size={35}
              color={focused ? "black" : "white"}
            />
          ),
        }}
      />
      <Tab.Screen
        name="MyGarden"
        component={MyGardenScreen}
        options={{
          tabBarIcon: ({ focused }) => (
            <FontAwesome6
              style={focused ? styles.focusedNavButtonBackground : {}}
              name="sun-plant-wilt"
              size={35}
              color={focused ? "black" : "white"}
            />
          ),
        }}
      />
    </Tab.Navigator>
  );
};

And this is the DiscoverScreen which is in both of the navigators:

const DiscoverScreen = ({ navigation }) => {
  const [getPlants, incrementPageNumber, page, plants, errorMessage] =
    usePlants();

  useEffect(() => {
    console.log("API called");
    getPlants(page);
  }, [page]);

  // ... rest of the component
};

Also, the usePlants logic:

useEffect(() => {
  console.log("API called");
  getPlants(page);
}, [page]);

Any help would be greatly appreciated!

I also tried to update only one of the navigators, but it caused the tab components or the stack to not update.

Upvotes: 0

Views: 38

Answers (1)

Thomasino73
Thomasino73

Reputation: 981

You have 2 Discover items

      <Stack.Screen
        name="Discover"
        component={DiscoverScreen}
        options={{ headerShown: false }}
      />

...

      <Tab.Screen
        name="Discover"
        component={DiscoverScreen}
        options={{
          tabBarIcon: ({ focused }) => (
            <FontAwesome
              style={focused ? styles.focusedNavButtonBackground : {}}
              name="search"
              size={35}
              color={focused ? "black" : "white"}
            />
          ),
        }}
      />

Simply renaming one of them should do the trick

For example

      <Stack.Screen
        name="Discover"
        component={DiscoverScreen}
        options={{ headerShown: false }}
      />

...

      <Tab.Screen
        name="DiscoverTab"
        component={DiscoverScreen}
        options={{
          tabBarIcon: ({ focused }) => (
            <FontAwesome
              style={focused ? styles.focusedNavButtonBackground : {}}
              name="search"
              size={35}
              color={focused ? "black" : "white"}
            />
          ),
        }}
      />

Upvotes: 0

Related Questions