React Native在两个屏幕之间来回导航

时间:2020-06-30 16:28:53

标签: react-native react-navigation

我有一个主屏幕屏幕,我们在其中搜索商品代码,搜索商品代码后,它将从API获取详细信息,并且该屏幕将导航至屏幕1 (“商品详细信息”屏幕) &从屏幕1中搜索ItemNutrients,搜索后将得到Nutrients,然后导航到屏幕2 (“ Nutrients屏幕”)

换句话说

主页->屏幕1(项目详细信息屏幕)->屏幕2(营养物屏幕)

从API中获取有关项目详细信息和营养的必要信息后,用户可以在项目详细信息和营养之间来回导航。

我可以从屏幕1 (项目详细信息)导航到屏幕2 (营养物屏幕),然后滑动回到屏幕1 (项目详细信息)但是我怎么能向前滑动以再次查看屏幕2 (营养物屏幕),而又没有在屏幕1 中搜索营养物,因为我已经有了营养物API的数据。

关于如何实现此目标的任何想法?这基本上是从屏幕1搜索时导航到屏幕1 屏幕2 ,或者如果屏幕2 搜索已经完成并且我们有数据,请滑动向前应该导航到屏幕2 ,我可以有一个按钮导航到屏幕2 ,只有当我们有营养物质屏幕的API数据时,屏幕1上的按钮才会出现会在单击该按钮时导航到屏幕2 ,但我还需要滑动功能才能向前导航

我在stackNavigator中有Home,Screen 1,Screen 2,还可以,或者我可以使用任何其他导航器来实现此目的。

我已经研究了如何执行此操作,但在任何地方的文档中都找不到它。如果我在某处缺少它,请告诉我。谢谢!

营养背景:

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

并在堆栈中导航:

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

我在堆栈周围有NutriSyncContextProvider,但是当我单击页面上的按钮时,它将在上下文类中调用nutrionScanClick方法,它的工作原理很好,但是当我导航时。标签不存在

我明白了,下面是代码:

 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]);

1 个答案:

答案 0 :(得分:1)

在堆栈导航器中,没有在屏幕之间来回滑动。您需要使用标签导航器才能保持多个屏幕。

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