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
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;
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.
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
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.
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:
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")}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With