简体   繁体   中英

React Native navigating between two screens back & forth

I have Home screen where we search for an ItemCode, after we search ItemCode it will get details from API & screen will navigate to Screen 1 (Item Details Screen) & from Screen 1 we have a search for ItemNutrients and after search it will get Nutrients & Navigate to Screen 2 (Nutrients Screen)

In other words

Home -> Screen 1 (Item Details Screen) -> Screen 2 (Nutrients Screen)

After getting the necessary details from API from search for Item Details & Nutrients, User can navigate between Item Details & Nutrients back and forth..

I could navigate from Screen 1 (item Details) to Screen2 (Nutrients Screen) and swipe back to Screen 1 (item Details) but how could I swipe forward to look at Screen 2 (Nutrients Screen) again without searching for nutrients in Screen 1 as I already have the data from API for Nutrients.

Any ideas on how to implement this? this is basically navigate to Screen 1 to Screen 2 on search from Screen 1 or if Screen 2 search is already done and we have data so swipe forward should navigate to Screen 2 , I can have a button to navigate to Screen 2 , the button on Screen 1 conditinally appears only when we have API data for Nutrients Screen and it will navigate to Screen 2 on that button click, but i need swipe functionality as well to navigate forward

I have Home, Screen 1, Screen 2 in stackNavigator, is it alright or i could use any other navigators to achieve this.

I have researched how to do this and can't find it in the docs anywhere. Please let me know if I am missing it somewhere. Thanks!

Nutrition Context:

import React, { createContext, useState, useEffect } from "react";

export const NutriSyncContext = createContext();

const DEFAULT_IS_NUTRI_SCANNED = false;

export const NutriSyncContextProvider = ({ children }) => {
  const [isNutritionScanned, setisNutritionScanned] = useState(
    DEFAULT_IS_NUTRI_SCANNED
  );

  // When we first mount the app we want to get the "latest" conversion data
  useEffect(() => {
    setisNutritionScanned(DEFAULT_IS_NUTRI_SCANNED);
  }, []);

  const nutrionScanClick = ({ navigation }) => {
    setisNutritionScanned(true);
    //navigation.navigate("NutritionFacts");
  };

  const contextValue = {
    isNutritionScanned,
    setisNutritionScanned,
    nutrionScanClick,
  };

  return (
    <NutriSyncContext.Provider value={contextValue}>
      {children}
    </NutriSyncContext.Provider>
  );
};

inside navigation.js

const tabPNMS = createMaterialTopTabNavigator();

function tabPNMSStackScreen() {
  const { isNutritionScanned } = useContext(NutriSyncContext);
  console.log(isNutritionScanned);

  return (
    <tabPNMS.Navigator initialRouteName="PNMSNutrition" tabBar={() => null}>
      <tabPNMS.Screen name="PNMSNutrition" component={PNMSNutrition} />
      {isNutritionScanned ? (
        <tabPNMS.Screen name="NutritionFacts" component={NutritionFacts} />
      ) : null}
    </tabPNMS.Navigator>
  );
}

and In stack Navigation:

const SearchStack = createStackNavigator();
const SearchStackScreen = () => (
  <NutriSyncContextProvider>
    <SearchStack.Navigator
      initialRouteName="Search"
      screenOptions={{
        gestureEnabled: false,
        headerStyle: {
          backgroundColor: "#101010",
        },
        headerTitleStyle: {
          fontWeight: "bold",
        },
        headerTintColor: "#ffd700",
        headerBackTitleVisible: false, //this will hide header back title
      }}
      headerMode="float"
    >
      <SearchStack.Screen
        name="Search"
        component={Search}
        options={({ navigation }) => ({
          title: "Search",
          headerTitleAlign: "center",
          headerLeft: () => (
            <Entypo
              name="menu"
              size={24}
              color="green"
              onPress={() => navigation.dispatch(DrawerActions.toggleDrawer())}
            />
          ),
        })}
      />
      <SearchStack.Screen
        name="NutriTabs"
        options={() => ({
          title: "PNMS",
          headerTitleAlign: "center",
        })}
        component={tabPNMSStackScreen}
      />
    </SearchStack.Navigator>
  </NutriSyncContextProvider>
);

I have NutriSyncContextProvider around the stack, but when I click the button on my page it will call nutrionScanClick method in context class it works just fine but when i do navigation.navigate to the NutritionFacts tab that is enabled i get error saying NutritionFacts tab doesn't exist

I got it working below is the code:

 const nutrionScanClick = () => {
    if (!isNutritionScanned) setisNutritionScanned(true);
    else {
      //Make a API call here for new data for the new scanned one's and then navigate
      navigation.navigate("NutritionFacts");
    }
  };

  useEffect(() => {
    if (isNutritionScanned) {
      navigation.navigate("NutritionFacts");
    }
  }, [isNutritionScanned]);

There's no swipe back n forth between screens in a stack navigator. You need to use a tab navigator to be able to keep multiple screens like that.

https://reactnavigation.org/docs/material-top-tab-navigator

import { createMaterialTopTabNavigator } from '@react-navigation/material-top-tabs';

const Tab = createMaterialTopTabNavigator();

function MyTabs() {
  return (
    <Tab.Navigator tabBar={() => null}>
      <Tab.Screen name="ItemDetails" component={ItemDetails} />
      {showNutrients ? <Tab.Screen name="Nutrients" component={Nutrients} /> : null}
    </Tab.Navigator>
  );
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM