Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why isn't react-native-onboarding-swiper working on my splash screen?

I have an application created doing my React Native studies. Once finished I have added some presentation screens and added 'react-native-onboarding-swiper' which seemed to me the easiest way that I found. I have also added '@react-native-async-storage/async-storage', before adding the splash screens, the App worked without AsyncStorage

The idea is that the App shows the presentation screens when we install it and open it for the first time, and then, it opens in the menu screen that I show.

EDIT AGAIN:

I need to correct the condition so that splash screens show only the first time the app is started, then it should boot to the home screen. 2 - The home screen is the one that I show in the screenshot and it shows me the button to "Go Back". I need this to go away

I cannot use headerShown: false, since in other screens that the application has if I must have the "Go Back" button How can I correct these problems in the simplest way?

Image enter image description here

The application works perfectly with the code in App.js that I show below, but it shows the presentation screens whenever the App is opened. I have created a condition to correct this, since I need the Presentation screens, to be shown, increase the first time the Application is opened. This is what App.js looks like before adding the else if:

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 SplashScreen from "react-native-splash-screen";

import NuevaOrden from "./views/NuevaOrden";
import OnboardingScreen from "./views/OnboardingScreen";

const Stack = createStackNavigator();

const App = () => {

//Hide Splash screen on app load.
  React.useEffect(() => {
    SplashScreen.hide();
  })  return (
    <>
      <FirebaseState>
        <PedidoState>
          <NavigationContainer>
            <Stack.Navigator
              screenOptions={{
                headerStyle: {
                  backgroundColor: "#FFDA00",
                },
                headerTitleStyle: {
                  fontWeight: "bold",
                },
                headerTintColor: "#000",
              }}
            >
              <Stack.Screen
                name="OnboardingScreen"
                component={OnboardingScreen}
                options={{
                  title: "Restaurante Paky",
                }}
              />

              <Stack.Screen
                name="NuevaOrden"
                component={NuevaOrden}
                options={{
                  title: "Restaurante Paky"
                }}
              />

              <Stack.Screen
                name="Menu"
                component={Menu}
                options={{
                  title: "Menú",
                  headerRight: props => <BotonResumen />
                }}
              />

              <Stack.Screen
                name="DetallePlato"
                component={DetallePlato}
                options={{
                  title: null
                }}
              />

              <Stack.Screen
                name="FormularioPlato"
                component={FormularioPlato}
                options={{
                  title: "Mi Pedido"
                }}
              />

              <Stack.Screen
                name="ResumenPedido"
                component={ResumenPedido}
                options={{
                  title: "Resumen Pedido"
                }}
              />

              <Stack.Screen
                name="ProgresoPedido"
                component={ProgresoPedido}
                options={{
                  title: "Progreso de Pedido"
                }}
              />
            </Stack.Navigator>
          </NavigationContainer>
        </PedidoState>
      </FirebaseState>
    </>
  );
};

export default App;

Everything works perfectly, but when I have placed the application inside an else if, it has broken showing the following error:

ExceptionsManager.js: 180

TypeError: Invalid attempt to destructure non-iterable instance.
In order to be iterable, non-array objects must have a [Symbol.iterator] () method.
This error is located at:
    in App (at renderApplication.js: 48)
    in RCTView (at View.js: 32)
    in View (at AppContainer.js: 106)
    in RCTView (at View.js: 32)
    in View (at AppContainer.js: 133)
    in AppContainer (at renderApplication.js: 41)
    in restaurantapp (RootComponent) (at renderApplication.js: 57)

I have looked for solutions without success, I need the splash screens to show only when we use the app for the first time, and then the App starts from the main menu This are my questions:

1 - Can I get this somehow? 2 - Can I add the presentation screens without using AsyncStorage?

I show the files involved:

File App.js

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.useEffect(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 if (isFirstLaunch === true) {
    return (
      <>
        <FirebaseState>
          <PedidoState>
            <NavigationContainer>
              <Stack.Navigator
                screenOptions={{
                  headerStyle: {
                    backgroundColor: "#FFDA00",
                  },
                  headerTitleStyle: {
                    fontWeight: "bold",
                  },
                  headerTintColor: "#000",
                }}
              >
                <Stack.Screen
                  name="OnboardingScreen"
                  component={OnboardingScreen}
                  options={{
                    title: "Restaurante Paky",
                  }}
                />

                <Stack.Screen
                name="NuevaOrden"
                component={NuevaOrden}
                options={{
                  title: "Restaurante Paky"
                }}
              />

              <Stack.Screen
                name="Menu"
                component={Menu}
                options={{
                  title: "Menú",
                  headerRight: props => <BotonResumen />
                }}
              />

              <Stack.Screen
                name="DetallePlato"
                component={DetallePlato}
                options={{
                  title: null
                }}
              />

              <Stack.Screen
                name="FormularioPlato"
                component={FormularioPlato}
                options={{
                  title: "Mi Pedido"
                }}
              />

              <Stack.Screen
                name="ResumenPedido"
                component={ResumenPedido}
                options={{
                  title: "Resumen Pedido"
                }}
              />

              <Stack.Screen
                name="ProgresoPedido"
                component={ProgresoPedido}
                options={{
                  title: "Progreso de Pedido"
                }}
              />
              </Stack.Navigator>
            </NavigationContainer>
          </PedidoState>
        </FirebaseState>
      </>
    );
  } else {
    return <NuevaOrden />;
  }
};

export default App;

File OnboardingScreen.js

import React from "react";
import { NavigationContainer } from "@react-navigation/native";
import { createStackNavigator, useNavigation } from "@react-navigation/stack";
import {
  View,
  Text,
  Button,
  Image,
  StyleSheet,
  TouchableOpacity,
} from "react-native";
import Onboarding from "react-native-onboarding-swiper";

const Dots = ({ selected }) => {
  let backgroundColor;

  backgroundColor = selected ? "rgba(0, 0, 0, 0.8)" : "rgba(0, 0, 0, 0.3)";

  return (
    <View
      style={{
        width: 6,
        height: 6,
        marginHorizontal: 3,
        backgroundColor,
      }}
    />
  );
};



const Next = ({ ...props }) => (
  <Button title="Next" color="#000000" {...props} />
);

const Done = ({ ...props }) => (
  <TouchableOpacity style={{ marginHorizontal: 8 }} {...props}>
    <Text style={{ fontSize: 16 }}>Done</Text>
  </TouchableOpacity>
);
const OnboardingScreen = ({ navigation }) => {
  return (
    <Onboarding
      SkipButtonComponent={Skip}      
      DoneButtonComponent={Done}
      DotComponent={Dots}
      onSkip={() => navigation.navigate("NuevaOrden")}       
      onDone={() => navigation.navigate("NuevaOrden")}
      pages={[
        {
          backgroundColor: "#a6e4d0",
          image: <Image source={require("../assets/onboarding-img1.png")} />,
          title: "Onboarding 1",
          subtitle: "Done with React Native Onboarding Swiper",
        },
        {
          backgroundColor: "#fdeb93",
          image: <Image source={require("../assets/onboarding-img2.png")} />,
          title: "Onboarding 2",
          subtitle: "Done with React Native Onboarding Swiper",
        },
        {
          backgroundColor: "#e9bcbe",
          image: <Image source={require("../assets/onboarding-img3.png")} />,
          title: "Onboarding 3",
          subtitle: "Done with React Native Onboarding Swiper",
        },
      ]}
    />
  );
};

export default OnboardingScreen;

like image 880
Miguel Espeso Avatar asked Sep 06 '21 11:09

Miguel Espeso


People also ask

How to create an onboarding screen in React Native?

Begin by creating a new React Native app and installing the dependency required to build the onboarding screens. Open up a terminal window and execute the commands below: If you are following this post using a plain React Native project and assuming you are on the latest version of React Native, the component installed is going to be auto-linked.

What is splash screen in React Native?

The React Native Logo splashes a new page. This is the most simple example to understand Splash Screen, i.e. text appears. 2. Animated Splash Screen in React Native

How to navigate through swipe using React-navigation?

At this library you can use swipe functions and in swipe functions you can navigate to any page. For navigating through swipe you can use createMaterialTopTabNavigator which was introduced in the react-navigation 2.x version.

How to add react-navigation library in React Native?

Start by adding react-navigation library by executing the following series of commands from a terminal window: Then, create a mock screen called Home.js inside src/screens/ directory with the following code snippet:


1 Answers

It seems you need to render the NuevaOrden component inside the NavigationContainer component, try conditionally rendering the onboarding screens with the and operator && and in your onboarding component call navigation.replace instead of navigation.navigate to set the NuevoPedido screen as the first screen and avoid the back button.

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;

in your Onboarding component

      onSkip={() => navigation.replace("NuevaOrden")}       
      onDone={() => navigation.replace("NuevaOrden")}
like image 141
diedu Avatar answered Oct 19 '22 19:10

diedu