splash screen react native - javascript

I'm starting an app and I have two views at the moment, one called Splash and the other called Home. It happens that when the splash is over it leads me to the Home view, but in this view the user presses the button backwards, the app shows me the splash again. Is there a way to avoid this? the idea is that being in the Home view there is no way to roll back the application.
MainStackNavigator.js
import * as React from 'react'
import { NavigationContainer } from '#react-navigation/native'
import { createStackNavigator } from '#react-navigation/stack'
import Splash from '../views/Splash/Splash';
import Home from '../views/Home/Home';
const Stack = createStackNavigator()
function MainStackNavigator() {
return (
<NavigationContainer>
<Stack.Navigator>
<Stack.Screen name='Splash' component={Splash} options={{ headerShown: false}} />
<Stack.Screen name='Home' component={Home} />
</Stack.Navigator>
</NavigationContainer>
)
}
export default MainStackNavigator
Splash.js
import React, { Component } from 'react'
import { View, ImageBackground, Image } from 'react-native'
// import SplashContext from '../../state/splashContext'
var bg = require('../../../assets/img/bg.png');
var logo = require('../../../assets/img/logo.png')
export default class Splash extends Component {
constructor(props) {
super(props);
setTimeout(() => {
this.props.navigation.navigate("Home");
}, 500)
}
render() {
return (
<ImageBackground
source={bg}
style={{ height: '100%', width: '100%' }}>
<View
style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
<Image source={logo}
style={{ height: 100, width: 100 }}
>
</Image>
</View>
</ImageBackground>
);
}
}
Home.js
import React, { Component } from 'react'
import { View, Text } from 'react-native'
export default class Splash extends Component {
render() {
return (
<View
style={{ flex: 1, padding: 10, alignItems: 'center', justifyContent: 'center' }}
>
<Text
style={{ fontSize: 30 }}
>Homse</Text>
</View>
);
}
}
App.js
import React from 'react';
import MainStackNavigator from './src/navigation/MainStackNavigator'
const App: () => React$Node = () => {
return (
<MainStackNavigator></MainStackNavigator>
);
};
export default App;

Using "navigate" will go to the next page adding it to the stack navigator. Instead you want to replace the current page (splash screen) with the home page. This can be done using
the replace function
this.props.navigation.replace("Home");
See https://reactnavigation.org/docs/navigation-prop/

You could use a modal to show the splash on the same screen while the information is loading instead of having two different views. Have a "loading" variable in the state of the view initialized to "true". This variable will be the "visibility" boolean for your modal. After everything loads, change the "loading" variable to "false".
Here's an example with "useState" hook:
const [isLoading, setIsLoading] = useState(true);
const loadInfo = async () => {
/*do your stuff*/
/*after stuff's done*/
setIsLoading(false);
};
if (isLoading) {
return (
<MySplashScreenModal/>
);
} else {
return (
<MyHomeScreen/>
);
}
The main reason for using the modal is because you can cover the entire screen with it, including the status bar.

I used this plugin for my android and ios app for the splash screen and it works great and smooth. I recommend everyone
React native bootsplash for splash screen

Related

Switching Between Screens with React Native Navigation and importing JS

I'm struggling to figure out why my code doesn't work. I keep reading the tutorials and nothing helps. How can I switch between screens and have the screens in different JS files (as components)?
Currently, my code works for the first screen, but when I click on the button nothing shows up.
Please see the codes below:
App.js
import * as React from 'react';
import {Button, View, Text } from 'react-native';
import { NavigationContainer } from '#react-navigation/native';
import { createNativeStackNavigator } from '#react-navigation/native-stack';
import TestScreen from './components/Test';
//HOME SCREEN
function HomeScreen({ navigation }) {
return (
<View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
<Text>Home Screen</Text>
<Button
title="Go to Test"
onPress={() => navigation.navigate('Test',{myParam: '03',})}
/>
</View>
);
}
const Stack = createNativeStackNavigator();
function App() {
return (
<NavigationContainer>
<Stack.Navigator initialRouteName="Home">
<Stack.Screen name="Home" component={HomeScreen} />
<Stack.Screen name="Test" component={TestScreen} />
</Stack.Navigator>
</NavigationContainer>
);
}
export default App;
Test.js
import React, { Component } from "react";
import { Text, View } from "react-native";
class Test extends Component {
render() {
const { navigation } = this.props;
return (
<View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
<Text>Test Screen</Text>
<Button
title="Test"
onPress={() => navigation.navigate('Home')}
/>
</View>
);
}
}
export default Test;
It seems it was a very simple issue and I figured it out myself. The code in Test.js was missing 'Button' in the import statement. The correct way should be:
import { Button, Text, View } from "react-native";
It's a silly mistake, but it's not the first time this happens to me. I use Visual Studio Code, which highlights missing connections, but it seems that this doesn't work for some components. Not to mention it compiles (bundling) with no problems.
Nevertheless, the code works fine now.
First you have to import useNavigation in Test.js file.
Like this:
import { useNavigation } from "#react-navigation/core";
Then you have to use it and save it in a variable like:
const navigation = useNavigation();
Now use:
onPress={() => navigation.navigate('Home')};
This will navigate to the the other Screen.
Make sure you install every library you use in your project using npm or yarn.

How to call a function to main App file? React Native

I have just started learning React Native. I am trying to insert bottom menu tabs on my first app.
I am using this code on Tabs.js (this is just the export part):
export default function Tabs() {
return (
<NavigationContainer>
<MyTabs />
</NavigationContainer>
);
}
Unfortunately, I don't know how to call it to my main App file (this is just one of my attempts):
import * as React from 'react';
import { Text, View } from 'react-native';
import Tabs from './Tabs.js';
Tabs();
I've read about exporting default function, but I don't understand how to use it in my main App file. I'm sure that this is a syntax issue.
Also, I am planning to add a background colour to all tabs. Any advice?
Thank you.
UPDATE:
This is my Tabs file.
import * as React from 'react';
import { Text, View } from 'react-native';
import { NavigationContainer } from '#react-navigation/native';
import { createBottomTabNavigator } from '#react-navigation/bottom-tabs';
import { MaterialCommunityIcons } from '#expo/vector-icons';
const Tabs = () => {
function Feed() {
return (
<View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
<Text></Text>
</View>
);
}
function Profile() {
return (
<View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
<Text></Text>
</View>
);
}
function MainPage() {
return (
<View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
<Text></Text>
</View>
);
}
const Tab = createBottomTabNavigator();
function MyTabs() {
return (
<Tab.Navigator
initialRouteName="Feed"
tabBarOptions={{
activeTintColor: '#e91e63',
}}
>
<Tab.Screen
name="Feed"
component={Feed}
options={{
tabBarLabel: '',
tabBarIcon: ({ color, size }) => (
<MaterialCommunityIcons name="home" color={color} size={size} />
),
}}
/>
<Tab.Screen
name="MainPage"
component={MainPage}
options={{
tabBarLabel: '',
tabBarIcon: ({ color, size }) => (
<MaterialCommunityIcons name="pill" color={color} size={size} />
),
}}
/>
<Tab.Screen
name="Profile"
component={Profile}
options={{
tabBarLabel: '',
tabBarIcon: ({ color, size }) => (
<MaterialCommunityIcons name="format-list-text" color={color} size={size} />
),
}}
/>
</Tab.Navigator>
);
}
return (
<NavigationContainer>
<MyTabs />
</NavigationContainer>
);
}
export default Tabs
This is my main App file.
import * as React from 'react';
import { Text, View } from 'react-native';
import Tabs from './Tabs.js';
const App=()=>{
return <Tabs />
}
Make sure to export the App as default. You most probably have a file called index.js in the root folder and that is importing your App component.
Your App.js file should look like this:
import * as React from 'react';
import { Text, View } from 'react-native';
import Tabs from './Tabs.js';
export default const App=()=>{
return <Tabs />
}
And then your index.js file looks like this:
import {AppRegistry} from 'react-native';
import App from './App';
import {name as appName} from './app.json';
AppRegistry.registerComponent(appName, () => App);
You don't necessarily have to export as default, because you can only have one default export. If you export App as default you import it like this: import App from './App'; and if you export without a default, you have to import like this: import {App} from './App'
And to get an advice how to add background color to the tabs, check here: How to set the background color of Tab.Navigator?
you basically call it like would call a component
btw your Tabs should export like this
const Tabs=()=>{
/...
}
export default Tabs
const App=()=>{
return <Tabs />
}

How can I have React Native navigation load component from another file?

I am trying to learn React Native navigation. This is my App.js, and it works fine, as expected:
import React, { Component } from 'react';
import { View, Text } from 'react-native';
import { NavigationContainer } from '#react-navigation/native';
import { createStackNavigator } from '#react-navigation/stack';
class App extends Component {
HomeScreen() {
return (
<View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
<Text>Home Screen</Text>
</View>
);
}
render() {
return (
<NavigationContainer>
<Stack.Navigator>
<Stack.Screen name="Home" component={this.HomeScreen} />
</Stack.Navigator>
</NavigationContainer>
)
}
}
const Stack = createStackNavigator();
export default App;
Here I have defined HomeScreen in the App.js file itself. But what if I wanted to define it as a standalone component in another file (say HomeScreen.js), like so -
import React, { Component } from 'react';
import { View, Text } from 'react-native';
class HomeScreen extends Component {
render() {
return (
<View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
<Text>Home Screen</Text>
</View>
)
}
}
export default HomeScreen;
How would I import and use that HomeScreen in App.js? I have tried import HomeScreen from './components/HomeScreen' and <Stack.Screen name="Home" component={HomeScreen} /> but that gives me an error saying that it's not a component. I know this is a simple, basic question, but so far I've not been able to find an answer anywhere. Is there a different navigation library I should be using to solve this problem?
I fixed it. What I was trying to do is give the component value JSX style, like component={<HomeScreen />} but it should just be component={HomeScreen}.

Horizontal margin too big on newly created Expo app

I just created a React Native app with Expo using expo init. Everything went fine. Then I went on and created a Home screen like so:
import React from 'react';
import { View, TextInput } from 'react-native';
export default class HomeScreen extends React.Component {
state = {
searchText: ""
}
render() {
return (
<View
style={{
flex: 1,
backgroundColor: 'white'
}}
>
<TextInput
placeholder="Search..."
value={this.state.searchText}
onChangeText={ (searchText) => this.setState({ searchText }) }
/>
</View>
);
}
}
I added it to my AppNavigator...
import { createAppContainer } from 'react-navigation';
import { createStackNavigator } from 'react-navigation-stack';
import HomeScreen from '../screens/HomeScreen';
const AppNavigator = createStackNavigator({
Home: HomeScreen
});
export default createAppContainer(AppNavigator);
...which I in turn added to App.js:
import React from 'react';
import { StyleSheet, View, StatusBar, Platform } from 'react-native';
import { AppLoading } from 'expo';
import AppNavigator from './navigation/AppNavigator';
export default class App extends React.Component {
state = {
isLoadingComplete: false
}
render() {
if (!this.state.isLoadingComplete && !this.props.skipLoadingScreen) {
return (
<AppLoading
startAsync={this._loadResourcesAsync}
onError={this._handleLoadingError}
onFinish={this._handleFinishLoading}
/>
);
}
return (
<View style={styles.container}>
{Platform.OS === 'ios' && <StatusBar barStyle="default" />}
<AppNavigator />
</View>
);
}
_loadResourcesAsync = async () => { };
_handleLoadingError = error => {
console.warn(error);
};
_handleFinishLoading = () => {
this.setState({ isLoadingComplete: true });
};
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#fff',
alignItems: 'center',
justifyContent: 'center',
},
});
Now, my problem is that my app looks like this:
As you can see, the horizontal margins are way too big, but I never set them to be like that. What am I doing wrong? I want the TextInput to stretch across the full screen.
Your HomeScreen Component will be as wide as its contents. You did not specify the width of the main View, therefore, it adjusted itself to be as wide the components inside. What you can do to resolve this issue is that you must provide width property in your Top level View's style.
And in order to get the Width of the screen, you can import Dimensions from react-native and use that like below:
const windowWidth = Dimensions.get('window').width;
and finally, you can assign the windowWidth to your view like so:
style={{flex:1, width: windowWidth, backgroundColor: 'white'}}

Is there a way to navigate to a different screen from the menu built in my Parent Component?

I am trying to add a simple customized navigation menu to my react-native app, but the issue that I am coming across right now is that I can't seem to find a way to navigate to the selected menu items corresponding screen. I tried the normal this.props.navigation.navigate('Home'), but it seems that there is no navigation prop, which makes sense because in my app I am assuming that the prop for navigation is passed down to the screens from my app.js through the use of <AppContainer />.
I have tried using the MainNavigator object in my App.js but it doesn't seem to be working and doesn't have a navigate function or anything like that.
I have also tried changing the structure of my render function in App.js a little bit but it still does not seem to be having much of an effect.
This is my App.js
import React, { Component } from 'react';
import {
View,
Text,
TouchableOpacity
} from 'react-native';
import {
createStackNavigator,
createAppContainer } from 'react-navigation';
// SCREEN
import MainScreen from './screens/MainScreen';
import CostAnalysis from './screens/CostAnalysis';
import DriverLog from './screens/DriverLog';
// SIDE MENU
import SideMenu from 'react-native-side-menu';
// REDUX IMPORTS
import { createStore, combineReducers } from 'redux';
import { Provider } from 'react-redux';
import { recordReducer } from './reducers/recordReducer';
import { databaseReducer } from './reducers/databaseReducer';
const MainNavigator = createStackNavigator({
Home: {screen: MainScreen},
DriverLog: {screen: DriverLog},
CostAnalysis: {screen: CostAnalysis},
}, {
defaultNavigationOptions: {
header: null
}
});
const AppContainer = createAppContainer(MainNavigator);
const rootReducer = combineReducers(
{records: recordReducer,
database: databaseReducer});
const store = createStore(rootReducer);
class App extends Component {
render() {
const menu = (<View style={{
backgroundColor: '#f0f0f0',
alignContent: 'center',
textAlign: 'center', height: '100%', width: '100%', paddingTop: '40%'}}>
<Text style={styles.menuTitle}>{'S K I P\nD R I V E R\nL O G'}</Text>
<TouchableOpacity onPress={() => {this.props.navigation.navigate('Home')}}>
<Text style={styles.menuItem}>HOME</Text>
</TouchableOpacity>
<TouchableOpacity onPress={() => {MainNavigator.navigate('DriverLog')}}>
<Text style={styles.menuItem}>DRIVING LOG</Text>
</TouchableOpacity>
</View>);
return (
<SideMenu menu={menu} >
<Provider store={store}>
<AppContainer />
</Provider>
</SideMenu>
);
}
}
const styles = {
menuTitle: {
marginBottom: 60,
fontSize: 40,
textAlign: 'center',
color: '#e74c3c'
},
menuItem: {
marginBottom: 10,
fontSize: 26,
textAlign: 'center'
}
}
export default (App);
Ideally I don't have to re-structure my entire app as I have made a lot of progress in other areas, but I would really like the menu to simply link to the correct places.
I'm still very new to react-native so I really don't know what else to try. If anyone can give me a hand it would be greatly appreciated!
Thanks :)
PS: See a picture of the menu to illustrate what I mean
Menu Screenshot
you have to implement the constructor
class App extends Component {
constructor(props) {
super(props);
}
}
or
if you are using a drawer use it as a separate component
import React, { Component } from 'react';
import {
View,
Text,
TouchableOpacity
} from 'react-native';
class SideDrawer extends Component{
constructor(props) {
super(props);
}
render(){
return(
<View style={{
backgroundColor: '#f0f0f0',
alignContent: 'center',
textAlign: 'center', height: '100%', width: '100%', paddingTop: '40%'}}>
<Text style={styles.menuTitle}>{'S K I P\nD R I V E R\nL O G'}</Text>
<TouchableOpacity onPress={() => {this.props.navigation.navigate('Home')}}>
<Text style={styles.menuItem}>HOME</Text>
</TouchableOpacity>
<TouchableOpacity onPress={() => {MainNavigator.navigate('DriverLog')}}>
<Text style={styles.menuItem}>DRIVING LOG</Text>
</TouchableOpacity>
</View>
)
}
}
export default sideDrawer
then in your navigator
const HomeNavigator = StackNavigator(
Home: {screen: MainScreen},
DriverLog: {screen: DriverLog},
CostAnalysis: {screen: CostAnalysis},
}
const MainNavigator = DrawerNavigator({
Home: {
screen: HomeNavigator,
},
}, {
contentComponent: sideDrawer,
drawerWidth: width * .7,
drawerOpenRoute: 'DrawerOpen',
drawerCloseRoute: 'DrawerClose',
drawerToggleRoute: 'DrawerToggle',
});

Categories