Expo splash screen or white screen after standalone apk is installed - react-native

I know this question has been asked several times but nowhere i found the answer. So I thought I will elaborate my question. Everything works fine in development. But when I make the standalone APK the splash screen doesn't goes away. I even tried to hide it after the component is loaded. That also doesn't work. What could be the issue ?
import { SplashScreen } from 'expo';
componentDidMount() {
setTimeout(function(){
SplashScreen.hide();
},2000);
}

try it:
create a screen: SplashScreen.js
and write the code bellow:
import React, { Component } from 'react';
import { View, StatusBar, Image } from 'react-native';
import introImage from '../assets/IntroPin3.gif';
export default class Loading extends Component {
render() {
return (
<View style={{ flex: 1, justifyContent:'center', alignItems:'center', backgroundColor: '#FDFDFF' }}>
<StatusBar hidden />
<Image
style={{height:350, width: 350 }}
source={ introImage}
/>
</View>
);
}
}
and in your app.js
write it:
import React, { Component } from 'react';
import SplashScreen from './Components/SplashScreen.js';
import Intro from './Components/Menu.js';
export default class Index extends Component {
state = {
ready: false,
};
componentDidMount() {
setTimeout(() => {
this.setState({ ready: true });
}, 5530);
}
render() {
if (this.state.ready === false) {
return <SplashScreen />;
}
return <Intro />;
}
}
try it, if this help you let me know.

import SplashScreen from 'react-native-splash-screen'
export default class WelcomePage extends Component {
componentDidMount() {
// do stuff while splash screen is shown
// After having done stuff (such as async tasks) hide the splash screen
SplashScreen.hide();
}
}
try this one... also you can read the documentation:
https://github.com/crazycodeboy/react-native-splash-screen

Related

React Native Expo Splash screen, async render

How to render react native component in the background? I want a splash screen, but the current example only allows async downloading data.
I have tried SplashScreen of AppLoading in Expo, but it only allows to download data first, it doesn't allow for async render for components.
import React from 'react';
import { Image, Text, View } from 'react-native';
import { Asset, SplashScreen } from 'expo';
export default class App extends React.Component {
state = {
isReady: false,
};
componentDidMount() {
SplashScreen.preventAutoHide();
}
render() {
if (!this.state.isReady) {
return (
<View style={{ flex: 1 }}>
<Image
source={require('./assets/images/splash.gif')}
onLoad={this._cacheResourcesAsync}
/>
</View>
);
}
return (
// ...
);
}
_cacheResourcesAsync = async () => {
SplashScreen.hide();
// ....
await Promise.all(cacheImages);
this.setState({ isReady: true });
}
}
This only download data asynchronously, but I want to render asynchronously.

Is there an easy way to create a logout button in the drawer in React Navigation V2?

I want to have logout button in my drawer. The problem is that it should not render a screen, but just straight up log out. Is there a easy way to do it (e.g. somehow modifying the contentOptions' items or onItemPressed property? I couldn't figure something out.
What I'm doing right now is writing a CustomDrawerComponent with a logout button in it, but it's pretty hard to get the styling right and look alike the other DrawerItems.
Here is how I solved this with a custom component. Maybe there is a different way?
import React, { PureComponent } from "react";
import { Image, ScrollView, Text, TouchableOpacity } from "react-native";
import { DrawerItems, SafeAreaView } from "react-navigation";
import { connect } from "react-redux";
import PropTypes from "prop-types";
import { clearToken } from "../../api/secureStorage/secureStorage";
import { BUTTON_TEXT_LOGOUT } from "../../config/constants/buttonTexts";
import { logout } from "../../redux/actions/logout/logout";
import styles from "./styles";
export class BurgerMenu extends PureComponent {
static propTypes = {
navigation: PropTypes.object,
logout: PropTypes.func.isRequired
};
logout = () => {
const { navigation, logout } = this.props;
clearToken().then(() => {
logout();
navigation.navigate("LoginScreen");
});
};
render() {
const { logout, ...strippedProps } = this.props; // eslint-disable-line no-unused-vars
return (
<SafeAreaView style={styles.container} forceInset={{ top: "always", horizontal: "never" }}>
<ScrollView>
<DrawerItems {...strippedProps} />
</ScrollView>
<TouchableOpacity style={[styles.footer, styles.item]} onPress={this.logout}>
<Image
source={require("../../assets/icons/exit.png")}
style={styles.icon}
resizeMode="contain"
/>
<Text style={styles.text}>{BUTTON_TEXT_LOGOUT}</Text>
</TouchableOpacity>
</SafeAreaView>
);
}
}
export default connect(
null,
{ logout }
)(BurgerMenu);

createBottomTabNavigator: how do I reload/refresh a tab screen on tab on the tab-icon?

So I have a TabNavigator with 3 screens.
import React from 'react';
import {TabNavigator,createBottomTabNavigator } from 'react-navigation';
import ActivateScannerPage from '../pages/ActivateScannerPage';
import ScanTicketPage from '../pages/ScanTicketPage';
import HomePage from '../pages/HomePage';
import SwipeList from '../components/SwipeList';
import FontAwesome, { Icons } from 'react-native-fontawesome';
import { Icon } from 'react-native-elements';
export default createBottomTabNavigator (
{
HomeScreen:{
screen:HomePage,
navigationOptions: {
tabBarIcon:()=>
<Icon
name='home'
type='font-awesome'
color='#5bc0de'/>
},
},
AcitvateScannerPage:{
screen:ActivateScannerPage,
navigationOptions: {
tabBarIcon:()=> <Icon
name='qrcode'
type='font-awesome'
color='#5bc0de'/>
},
},
ScanTicketPage:{
screen:ScanTicketPage,
navigationOptions: {
tabBarIcon:()=> <Icon
name='ticket'
type='font-awesome'
color='#5bc0de'/>
},
},
},
{
tabBarOptions: {
activeTintColor: '#5bc0de',
inactiveTintColor :'white',
labelStyle: {
fontSize: 12,
},
style: {
backgroundColor: '#444444'
},
}
}
);
When I click on ActivateScannerPage there will be opened the camera for scanning a QR Code.
import React, { Component } from 'react';
import {
StyleSheet,
View,
} from 'react-native';
import QrCode from '../components/QrCode';
class ActivateScannerPage extends Component {
static navigationOptions = {
title: 'Aktivierung Scanner',
};
constructor (props){
super(props);
}
render(){
return(
<View style={styles.viewContent}>
<QrCode scanner={true} headerText="Aktivieren Sie Ihren Scanner"/>
</View>
);
}
}
const styles = StyleSheet.create({
viewContent:{
flex:1
}
});
export default ActivateScannerPage;
So my problem ist when the app starts and I click on the tab "ActivateScannerPage/Aktivierung Scanner" then it opens the camera and I can scan my codes without a problem. But when I tab to another tabScreen, e.g. back to the home screen and then go back to the AcitivateScannerPage, the view is not refreshed or rendered new. So the camera dont open anymore and I see a black screen.
Is there a way to fix this? Can I reload or rerender the screen by tapping on the tabIcon?
Thanks.
EDIT:
import React, { Component } from 'react';
import {
AppRegistry,
StyleSheet,
Text,
View,
AsyncStorage,
} from 'react-native';
import QRCodeScanner from 'react-native-qrcode-scanner';
import moment from 'moment';
import { Icon } from 'react-native-elements';
class QrCode extends Component {
static navigationOptions=(props)=>({
title: `${props.navigation.state.params.scannerName}`,
headerTintColor: 'white',
headerStyle: {backgroundColor: '#444444'},
headerTitleStyle: { color: 'white' },
})
constructor(props){
super(props);
this.state={
.....some states.....
}
}
onSuccess(e) {
..... do something..... here I get my data which I use
}
fetchDataScanner(dataMacroID,requestKey,hash) {
......
}
fetchDataTicketCheck(dataMacroID,requestKey,ticketValue){
.....
}
fetchDataTicketValidate(dataMacroID,requestKey,dataMicroID,ticketValue){
.....
}
saveDataScannerActivation=()=>{
.....
}
render() {
return (
<View style={styles.viewContent}>
<View style={{flex:4}}>
<QRCodeScanner
reactivateTimeout={2000}
reactivate={true}
onRead={this.onSuccess.bind(this)}
/>
</View>
</View>
);
}
}
......
export default QrCode;
in screens you designed for your tabs have to do flowing steps:
1: import withNavigationFocus from react-navigation to your class .
2: then export your like this : export default withNavigationFocus(yourclassname)
3: use this code to update or manage your state
shouldComponentUpdate = (nextProps, nextState) => {
if (nextProps.isFocused) {
...
return true;
} else {
...
return false;
}
};
With react-navigation you can detect whenever the ActivateScannerPage is active/tapped.
Add this code in componentDidMount in ActivateScannerPage
this.subs = [
this.props.navigation.addListener('didFocus', () => this.isFocused()),
];
And remove the listener if ActivateScannerPage will unmount
componentWillUnmount() {
this.subs.forEach(sub => sub.remove());
}

Expo AppLoading and app bootstrap data?

There is a new component <AppLoading/> that is supposed to let the splash screen remain visible while loading app resources.
The example in the doc is pretty straightforward
https://docs.expo.io/versions/latest/sdk/app-loading.html
import React from 'react';
import { Image, Text, View } from 'react-native';
import { Asset, AppLoading } from 'expo';
export default class App extends React.Component {
state = {
isReady: false,
};
render() {
if (!this.state.isReady) {
return (
<AppLoading
startAsync={this._cacheResourcesAsync}
onFinish={() => this.setState({ isReady: true })}
onError={console.warn}
/>
);
}
return (
<View style={{ flex: 1 }}>
<Image source={require('./assets/images/expo-icon.png')} />
<Image source={require('./assets/images/slack-icon.png')} />
</View>
);
}
async _cacheResourcesAsync() {
const images = [
require('./assets/images/expo-icon.png'),
require('./assets/images/slack-icon.png'),
];
const cacheImages = images.map((image) => {
return Asset.fromModule(image).downloadAsync();
});
return Promise.all(cacheImages)
}
}
However is this kind of component intended to handle loading resources that can fail?
Like for example if my app needs bootstrap datas regarding the authenticated users, provided by a backend, should I use this component?
If AppLoading is suited for this need, how would you handle the case where the user starts the app with no connexion, and the bootstrap data promise rejects? How do you handle retry attempts?

Disable console log in react navigation

I'm using react navigation for my app development. When i run log-android, it keeps logging something like this.
Navigation Dispatch: Action: {...}, New State: {...}
which is from createNavigationContainer.js line 150.
I've run through github and document said it could be done by by setting onNavigationStateChange={null} on a top-level navigator.
How can i achieve this by setting onNavigationStateChange={null} and where should i set it?
I've try to set like below, but it the page will not be able to redirect to other page.
export default () => {
<App onNavigationStateChange={null} />
}
Below are my app.js code
import React, { Component } from 'react';
import { AppRegistry, StyleSheet, Text, View } from 'react-native';
import { StackNavigator,DrawerNavigator } from 'react-navigation';
import DrawerContent from './components/drawer/drawerContent.js';
import News from './components/news/home.js';
const drawNavigation = DrawerNavigator(
{
Home : {
screen : News ,
navigationOptions : {
header : null
}
}
},
{
contentComponent: props => <DrawerContent {...props} />
}
)
const StackNavigation = StackNavigator({
Home : { screen : drawNavigation,
navigationOptions: {
header: null
}
}
});
export default StackNavigation;
This is my drawerContent.js
import React, {Component} from 'react'
import {View,Text, StyleSheet,
TouchableNativeFeedback,
TouchableOpacity,
TouchableHighlight
} from 'react-native'
import { DrawerItems, DrawerView } from 'react-navigation';
import Icon from 'react-native-vector-icons/Octicons';
import MaterialIcons from 'react-native-vector-icons/MaterialIcons';
class DrawerContent extends Component {
constructor(props){
super(props);
console.log('DrawerContent|testtttttt');
}
render(){
return (
<View style={styles.container}>
<Text>Hi darren</Text>
<TouchableOpacity style={{ marginBottom:5 }} onPress={() => this.props.navigation.navigate('RegistrationScreen') } >
<View style={styles.nonIconButton}>
<Text style={{ color: 'black',fontSize: 13 }} >Sign Up</Text>
</View>
</TouchableOpacity>
<Text>Hi darren</Text>
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
},
});
export default DrawerContent;
First, make sure you are using the latest release of react-navigation as the comment noting that the fix was committed is fairly recent.
Based on your code example, to disable logging for all navigation state changes, you would want to replace this code:
export default StackNavigation;
with:
export default () => (
<StackNavigation onNavigationStateChange={null} />
);
as StackNavigation appears to be your root navigator.
React navigation is great, but this logging is really bad. Solution
const AppNavigator = StackNavigator(SomeAppRouteConfigs);
class App extends React.Component {
render() {
return (
<AppNavigator onNavigationStateChange={null} />
);
}
}