为什么 React-native-onboarding-swiper 无法在我的启动屏幕上运行?

Mig*_*eso 8 javascript splash-screen reactjs react-native use-effect

我创建了一个应用程序来进行 React Native 研究。\n完成后,我添加了一些演示屏幕并添加了 \',react-native-onboarding-swiper\'这对我来说似乎是我发现的最简单的方法。\n我还添加了\'@react-native-async-storage/async-storage\',在添加启动屏幕之前,该应用程序可以正常工作没有AsyncStorage

\n

这个想法是,当我们安装它并第一次打开它时,该应用程序会显示演示屏幕,然后,它会在我显示的菜单屏幕中打开。

\n

再次编辑:

\n

我需要纠正这种情况,以便启动画面仅在应用程序第一次启动时显示,然后它应该启动到主屏幕。\n2 - 主屏幕是我在屏幕截图中显示的屏幕,它向我显示了按钮到"Go Back"。我需要这个消失

\n

我无法使用 headerShown: false,因为在应用程序具有的其他屏幕中,如果我必须有该"Go Back"按钮\n如何以最简单的方式纠正这些问题?

\n

图片\n在此输入图像描述

\n

该应用程序与我在下面显示的 App.js 中的代码完美配合,但每当打开应用程序时它都会显示演示屏幕。我创建了一个条件来纠正此问题,因为我需要在第一次打开应用程序时增加显示的演示屏幕。这是添加之前 App.js 的样子else if

\n
import "react-native-gesture-handler";\nimport React, { useEffect } from "react";\n\nimport { NavigationContainer } from "@react-navigation/native";\nimport { createStackNavigator } from "@react-navigation/stack";\nimport AsyncStorage from "@react-native-async-storage/async-storage";\nimport SplashScreen from "react-native-splash-screen";\n\nimport NuevaOrden from "./views/NuevaOrden";\nimport OnboardingScreen from "./views/OnboardingScreen";\n\nconst Stack = createStackNavigator();\n\nconst App = () => {\n\n//Hide Splash screen on app load.\n  React.useEffect(() => {\n    SplashScreen.hide();\n  })  return (\n    <>\n      <FirebaseState>\n        <PedidoState>\n          <NavigationContainer>\n            <Stack.Navigator\n              screenOptions={{\n                headerStyle: {\n                  backgroundColor: "#FFDA00",\n                },\n                headerTitleStyle: {\n                  fontWeight: "bold",\n                },\n                headerTintColor: "#000",\n              }}\n            >\n              <Stack.Screen\n                name="OnboardingScreen"\n                component={OnboardingScreen}\n                options={{\n                  title: "Restaurante Paky",\n                }}\n              />\n\n              <Stack.Screen\n                name="NuevaOrden"\n                component={NuevaOrden}\n                options={{\n                  title: "Restaurante Paky"\n                }}\n              />\n\n              <Stack.Screen\n                name="Menu"\n                component={Menu}\n                options={{\n                  title: "Men\xc3\xba",\n                  headerRight: props => <BotonResumen />\n                }}\n              />\n\n              <Stack.Screen\n                name="DetallePlato"\n                component={DetallePlato}\n                options={{\n                  title: null\n                }}\n              />\n\n              <Stack.Screen\n                name="FormularioPlato"\n                component={FormularioPlato}\n                options={{\n                  title: "Mi Pedido"\n                }}\n              />\n\n              <Stack.Screen\n                name="ResumenPedido"\n                component={ResumenPedido}\n                options={{\n                  title: "Resumen Pedido"\n                }}\n              />\n\n              <Stack.Screen\n                name="ProgresoPedido"\n                component={ProgresoPedido}\n                options={{\n                  title: "Progreso de Pedido"\n                }}\n              />\n            </Stack.Navigator>\n          </NavigationContainer>\n        </PedidoState>\n      </FirebaseState>\n    </>\n  );\n};\n\nexport default App;\n
Run Code Online (Sandbox Code Playgroud)\n

一切工作正常,但是当我将应用程序放入 an 中时else if,它已损坏并显示以下错误:

\n
ExceptionsManager.js: 180\n\nTypeError: Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator] () method.\nThis error is located at:\n    in App (at renderApplication.js: 48)\n    in RCTView (at View.js: 32)\n    in View (at AppContainer.js: 106)\n    in RCTView (at View.js: 32)\n    in View (at AppContainer.js: 133)\n    in AppContainer (at renderApplication.js: 41)\n    in restaurantapp (RootComponent) (at renderApplication.js: 57)\n
Run Code Online (Sandbox Code Playgroud)\n

我寻找解决方案但没有成功,我需要仅在第一次使用该应用程序时显示启动画面,然后应用程序从主菜单启动\n这是我的问题:

\n

1 - 我能以某种方式得到这个吗?\n2 - 我可以在不使用 AsyncStorage 的情况下添加演示屏幕吗?

\n

我显示涉及的文件:

\n

文件 App.js

\n
import "react-native-gesture-handler";\nimport React, { useEffect } from "react";\n\nimport { NavigationContainer } from "@react-navigation/native";\nimport { createStackNavigator } from "@react-navigation/stack";\nimport AsyncStorage from "@react-native-async-storage/async-storage";\n\nimport OnboardingScreen from "./views/OnboardingScreen";\n\nconst Stack = createStackNavigator();\n\nconst App = () => {\n  const [isFirstLaunch, setIsFirstLaunch] = React.useEffect(null);\n\n  useEffect(() => {\n    AsyncStorage.getItem("alreadyLaunched").then((value) => {\n      if (value == null) {\n        AsyncStorage.setItem("alreadyLaunched", "true");\n        setIsFirstLaunch(true);\n      } else {\n        setIsFirstLaunch(false);\n      }\n    });\n  }, []);\n\n  if (isFirstLaunch === null) {\n    return null;\n  } else if (isFirstLaunch === true) {\n    return (\n      <>\n        <FirebaseState>\n          <PedidoState>\n            <NavigationContainer>\n              <Stack.Navigator\n                screenOptions={{\n                  headerStyle: {\n                    backgroundColor: "#FFDA00",\n                  },\n                  headerTitleStyle: {\n                    fontWeight: "bold",\n                  },\n                  headerTintColor: "#000",\n                }}\n              >\n                <Stack.Screen\n                  name="OnboardingScreen"\n                  component={OnboardingScreen}\n                  options={{\n                    title: "Restaurante Paky",\n                  }}\n                />\n\n                <Stack.Screen\n                name="NuevaOrden"\n                component={NuevaOrden}\n                options={{\n                  title: "Restaurante Paky"\n                }}\n              />\n\n              <Stack.Screen\n                name="Menu"\n                component={Menu}\n                options={{\n                  title: "Men\xc3\xba",\n                  headerRight: props => <BotonResumen />\n                }}\n              />\n\n              <Stack.Screen\n                name="DetallePlato"\n                component={DetallePlato}\n                options={{\n                  title: null\n                }}\n              />\n\n              <Stack.Screen\n                name="FormularioPlato"\n                component={FormularioPlato}\n                options={{\n                  title: "Mi Pedido"\n                }}\n              />\n\n              <Stack.Screen\n                name="ResumenPedido"\n                component={ResumenPedido}\n                options={{\n                  title: "Resumen Pedido"\n                }}\n              />\n\n              <Stack.Screen\n                name="ProgresoPedido"\n                component={ProgresoPedido}\n                options={{\n                  title: "Progreso de Pedido"\n                }}\n              />\n              </Stack.Navigator>\n            </NavigationContainer>\n          </PedidoState>\n        </FirebaseState>\n      </>\n    );\n  } else {\n    return <NuevaOrden />;\n  }\n};\n\nexport default App;\n
Run Code Online (Sandbox Code Playgroud)\n

文件 OnboardingScreen.js

\n
import React from "react";\nimport { NavigationContainer } from "@react-navigation/native";\nimport { createStackNavigator, useNavigation } from "@react-navigation/stack";\nimport {\n  View,\n  Text,\n  Button,\n  Image,\n  StyleSheet,\n  TouchableOpacity,\n} from "react-native";\nimport Onboarding from "react-native-onboarding-swiper";\n\nconst Dots = ({ selected }) => {\n  let backgroundColor;\n\n  backgroundColor = selected ? "rgba(0, 0, 0, 0.8)" : "rgba(0, 0, 0, 0.3)";\n\n  return (\n    <View\n      style={{\n        width: 6,\n        height: 6,\n        marginHorizontal: 3,\n        backgroundColor,\n      }}\n    />\n  );\n};\n\n\n\nconst Next = ({ ...props }) => (\n  <Button title="Next" color="#000000" {...props} />\n);\n\nconst Done = ({ ...props }) => (\n  <TouchableOpacity style={{ marginHorizontal: 8 }} {...props}>\n    <Text style={{ fontSize: 16 }}>Done</Text>\n  </TouchableOpacity>\n);\nconst OnboardingScreen = ({ navigation }) => {\n  return (\n    <Onboarding\n      SkipButtonComponent={Skip}      \n      DoneButtonComponent={Done}\n      DotComponent={Dots}\n      onSkip={() => navigation.navigate("NuevaOrden")}       \n      onDone={() => navigation.navigate("NuevaOrden")}\n      pages={[\n        {\n          backgroundColor: "#a6e4d0",\n          image: <Image source={require("../assets/onboarding-img1.png")} />,\n          title: "Onboarding 1",\n          subtitle: "Done with React Native Onboarding Swiper",\n        },\n        {\n          backgroundColor: "#fdeb93",\n          image: <Image source={require("../assets/onboarding-img2.png")} />,\n          title: "Onboarding 2",\n          subtitle: "Done with React Native Onboarding Swiper",\n        },\n        {\n          backgroundColor: "#e9bcbe",\n          image: <Image source={require("../assets/onboarding-img3.png")} />,\n          title: "Onboarding 3",\n          subtitle: "Done with React Native Onboarding Swiper",\n        },\n      ]}\n    />\n  );\n};\n\nexport default OnboardingScreen;\n\n
Run Code Online (Sandbox Code Playgroud)\n

die*_*edu 3

看来您需要NuevaOrden在组件内部渲染组件NavigationContainer,尝试使用 and 运算符有条件地渲染载入屏幕,&&并在载入组件调用中,navigation.replace而不是navigation.navigate将 NuevoPedido 屏幕设置为第一个屏幕并避免使用后退按钮

import "react-native-gesture-handler";
import React, { useEffect } from "react";

import { NavigationContainer } from "@react-navigation/native";
import { createStackNavigator } from "@react-navigation/stack";
import AsyncStorage from "@react-native-async-storage/async-storage";

import OnboardingScreen from "./views/OnboardingScreen";

const Stack = createStackNavigator();

const App = () => {
  const [isFirstLaunch, setIsFirstLaunch] = React.useState(null);

  useEffect(() => {
    AsyncStorage.getItem("alreadyLaunched").then((value) => {
      if (value == null) {
        AsyncStorage.setItem("alreadyLaunched", "true");
        setIsFirstLaunch(true);
      } else {
        setIsFirstLaunch(false);
      }
    });
  }, []);

  if (isFirstLaunch === null) {
    return null;
  } else {
    return (
      <>
        <FirebaseState>
          <PedidoState>
            <NavigationContainer>
              <Stack.Navigator
                screenOptions={{
                  headerStyle: {
                    backgroundColor: "#FFDA00",
                  },
                  headerTitleStyle: {
                    fontWeight: "bold",
                  },
                  headerTintColor: "#000",
                }}
              >
                {isFirstLaunch && (
                  <Stack.Screen
                    name="OnboardingScreen"
                    component={OnboardingScreen}
                    options={{
                      title: "Restaurante Paky",
                    }}
                  />
                )}
                <Stack.Screen
                  name="Nueva Orden"
                  component={NuevaOrden}
                  options={{
                    title: "Nueva orden",
                  }}
                />
                <Stack.Screen
                  name="Menu"
                  component={Menu}
                  options={{
                    title: "Restaurante Paky",
                  }}
                />
                ... here the rest of your screens
              </Stack.Navigator>
            </NavigationContainer>
          </PedidoState>
        </FirebaseState>
      </>
    );
  }
};

export default App;
Run Code Online (Sandbox Code Playgroud)

在您的入职组件中

      onSkip={() => navigation.replace("NuevaOrden")}       
      onDone={() => navigation.replace("NuevaOrden")}
Run Code Online (Sandbox Code Playgroud)