Hiding the status bar with React Native - reactjs

How do you hide the status bar for iOS or Android when developing with React Native? I've imported StatusBar, but I believe there is also StatusBarIOS and a StatusBar for Android.

Figured out how to hide the status bar. First of all, StatusBarIOS is deprecated so you need to import StatusBar and then simply include this code snippet at the top of your render:
<StatusBar hidden />
React Native Docs on StatusBar

You can invoke this method from anywhere in your component:
import React, { Component } from 'react';
import { StatusBar } from 'react-native';
class MyComponent extends Component {
componentDidMount() {
StatusBar.setHidden(true);
}
}
EDIT:
This will hide the status bar for the entire app and not just in your specific component, to solve this you can do:
componentWillUnmount() {
StatusBar.setHidden(false);
}
Or calling this method with false from somewhere else.

For Hidden:
StatusBar.setHidden(true, 'none');
For Show:
StatusBar.setHidden(false, 'slide');

I prefer the simple way of importing the StatusBar component and passing true to hidden prop...
So Simply:
import React from "react";
import { StatusBar, View, Text } from "react-native";
class App extends React.Component {
render() {
return (
<View>
<StatusBar hidden={true} />
<Text>Hello React Native!</Text>
</View>
)
}
}

From version 0.?? to current (0.55 / June 2018)
<StatusBar hidden />
Credit to the first comment in this answer
Remember to first import the StatusBar component as per the other answers here

If your reason for hiding it is to prevent your components from overlapping it, you might prefer to just use SafeAreaView as follows:
<SafeAreaView style={{flex: 1, backgroundColor: '#fff'}}>
<View style={{flex: 1}}>
<Text>Hello World!</Text>
</View>
</SafeAreaView>
It should be the parent component of a screen and can optionally use a backgroundColor to match the color of your screen. Make sure to set a flex attribute. Your components will now just take up any area not being used by the status bar. This is especially useful in getting around the 'notch' issue with some of the newer phones.
SafeAreaView is a component of react-native so you will need to make sure you add it to your imports:
import { SafeAreaView, Text, View } from 'react-native';

to make it transparent on android you can do this
<StatusBar backgroundColor={'#ffffff00'} />
{Platform.OS === 'ios' && <StatusBar barStyle="light-content" />}
also <StatusBar hidden /> is hidden it but you may see a margin on top

It hasn't worked doesn't matter what you have tried?
Maybe there is another <StatusBar hidden="false"> in your code. And it is deeper than your definition. This will replace your previous hidden="true" setting.
<View>
<StatusBar hidden={true} /> // this will be replaced by the deeper StatusBar tag
<View>
<StatusBar hidden={false} /> // remove this or put your `hidden="true"` here
</View>
</View>

Related

StatusBar Background Color in Expo (React Native) doesn't work

StatusBar backgroundColor prop doesn't work, in Expo Snack too. Work only props hidden and barStyle. Code example from Expo Snack:
import * as React from 'react';
import { Text, View, StyleSheet, StatusBar } from 'react-native';
import Constants from 'expo-constants';
// You can import from local files
import AssetExample from './components/AssetExample';
// or any pure javascript modules available in npm
import { Card } from 'react-native-paper';
export default class App extends React.Component {
render() {
return (
<View style={styles.container}>
<StatusBar backgroundColor="white" barStyle="dark-content" hidden={false} translucent={false}/>
<Text style={styles.paragraph}>
Change code in the editor and watch it change on your phone! Save to get a shareable url.
</Text>
<Card>
<AssetExample />
</Card>
</View>
);
}
}
I also tried to add a style in the app.json:
{
"expo": {
...
"androidStatusBar": {
"backgroundColor": "#ffffff"
}
}
}
and
"androidStatusBarColor": "#ffffff", "androidStatusBar": { "barStyle": "dark-content", "backgroundColor": "#ffffff" }
What do i wrong?
Thanks!
It's an Expo problem, the community has been asking for a solution for some time. But it seems that in the next versions of Expo the problem will be solved.
You can follow this situation here: https://github.com/expo/expo/issues/2813

React Native : Custom Tabbar

React native : How can I custom tab bar like image below??
1) you can use this library to create tabs react-native-scrollable-tab-view.
2) Then it has a prop (renderTabBar) here you can pass your own custom tab bar.
<ScrollableTabView renderTabBar={() => <DefaultTabBar tabStyle={{color: 'red'}} />} />
one tip that i am giving.
make a file name it CustomTabBar copy all the code from libraries DefaultTabBar and past it in your CustomTabBar.
now change its designs the way you want it to be and use it like this. This way you will have to do the least amount of work.
<ScrollableTabView renderTabBar={() => <CustomTabBar/>} />
Maybe this is the solution you need
1, Install: switch-react-native
npm i switch-react-native
2, Using lib:
import React, { Component } from 'react';
import { View } from 'react-native';
import { Switch } from 'switch-react-native';
class SwitchExample extends Component {
render() {
return (
<View>
<Switch
height={40}
width={300}
activeText={`Active Text`}
inActiveText={`InActive Text`}
onValueChange={(value: any) => console.log(value)}
/>
</View>
);
}
}

Reloading an animation React-native-animatable library

guy's I'm using the react-native-animatable library. Basically, when I load my app the animation runs, however, when I go to another tab and return to the initial page the animation doesn't run anymore. I think it's because it' doesn't get reloaded anymore and I was wondering how to reload a component. As you can see the View has an animation prop which is the animation which has to be loaded.
import React, { Component } from 'react';
import { Text, Button, StyleSheet, Image, ImageBackground, TouchableOpacity } from 'react-native';
import Icon from 'react-native-vector-icons/MaterialCommunityIcons';
import LinearGradient from 'react-native-linear-gradient';
import {Fonts} from '../components/Fonts';
import { createAnimatableComponent, View, } from 'react-native-animatable';
class Home extends React.Component {
render() {
return (
<View style={styles.container}>
<View animation='bounceInLeft'
style={styles.container1}>
<View style={styles.card1}>
<ImageBackground
source={require('../images/pictures/runop.jpg')}
style={{width:'100%', height:200, }}>
<Text
style={{fontSize:30, alignSelf:'center', color:'white',
fontFamily:Fonts.Nunito}}
> Sport Schema's</Text>
</ImageBackground>
</View>
</View>
<View animation='bounceInRight' style={styles.container2}>
<View style={styles.card2}>
<Image
source={require('../images/pictures/foodop.jpg')}
style={{width:'100%', height:200}}/>
</View>
</View>
<View animation='bounceInLeft' style={styles.container3}>
<View style={styles.card3}>
<Image
source={require('../images/pictures/blogop.jpg')}
style={{width:'100%', height:200}}/>
</View>
</View>
</View>
);
}
}
Thanks for your help. I eventually got it to work with a different method.
I used the withNavigationFocus from react-navigation to get the isFocused props of the current screen. Then i just used an if statement if screen is focused then run animation else dont.
import {withNavigationFocus} from 'react-navigation';
class Profile extends React.Component {
constructor(props) {
super(props);
}
render()
// This checks if current screen is focused then run the animation otherwise dont.
{
if (this.props.isFocused && this.animation) {
this.animation.bounce(800)
}
return (
<View ref={(ref) => {this.animation = ref;}}
style={styles.container3}>
<View style={styles.card3}>
<Text> hii</Text>
</View>
</View>
);
}
}
});
export default withNavigationFocus(Profile); // <- dont forget this!!
If you are using react-navigation, below solution might work for you.
Create a function which would start the animation after some milliseconds and pass it to the next screen as params. Example,
SCREEN A
animateFunction() {
setTimeout(() => {
// start your animation
}, 100);
}
navigation.navigate(SCREEN_NAME, { startPrevScreenAnimation: animateFunction });
And in the next screen call that function when the component unmounts (componentWillUnmount()). Example,
SCREEN B
componentWillUnmount() {
this.props.navigation.state.params.startPrevScreenAnimation();
}
I said some milliseconds because you would want the animation to start once the screen transition is complete.
OR
Add a listener to your screen which fires an event when the screen is in focus.
if (this.props.navigation) {
this.willFocusSubscription = this.props.navigation.addListener(
'willFocus',
() => { // Run your animation },
);
}

Bad practise to generate new StyleSheet every render?

Every documentation example that I have read about creating a StyleSheet for a component has done it outside of render() (even like a regular variable outside the component class). Doing it that way means I have no control over props or state changes that can manipulate the style of said component. As such I have been calling a getStyles() function inside the render() method which creates a (new) StyleSheet on every render. To me it sounds expensive performance-wise, but it does the job. However, I’m wondering if there is a better way of doing it?
Thanks in advance!
Yes! Accourding to the StyleSheet Docs it is not the best idea to create a StyleSheet during every render because of performance and code-readability.
There is a better way of doing it by using array notations, basically meaning you can pass in an array of style objects
for instance if I had a component that has it's background color and text color set in a styles object like this:
import React, { Component } from 'react';
import { StyleSheet, Text, View } from 'react-native';
export default class SomeComponent extends Component{
render(){
return(
<View style={styles.root}>
<Text>{'Hi Everybody!'}</Text>
</View>
);
}
}
const styles = StyleSheet.create({
root: {
backgroundColor: '#000000',
height: 400,
width: 300,
color: 'white'
}
});
You can customize it the background color(or any other style) like so:
<View style={[styles.root, {backgroundColor: "yellow"}]}>
<Text>{'Hi Everybody!'}</Text>
</View>
In your case, you might pass in a props value like so :
<View style={[styles.root, this.props.style]}>
<Text>{'Hi Everybody!'}</Text>
</View>
or a variable from the state object like so :
<View style={[styles.root, this.state.style]}>
<Text>{'Hi Everybody!'}</Text>
</View>
The later values in the array will take precedence, so if I added yet another style object that has a backgroundColor attribute, the last backgroundColor will be applied;
For example if I did this:
<View style={[styles.root, {backgroundColor: "yellow"}, {backgroundColor: "green"}]}>
<Text>{'Hi Everybody!'}</Text>
</View>
the background color will be green.
So you can now write your code in such a way that the styles created with StyleSheet.create({}) will contain the boilerplate styles that are constant and apply to any customization, or just the default styles.
Hope that helps.

React-native: Super expression must either be null or a function, not undefined

I have seen similar questions asked but I can't seem to indentify the problem.
I am using react native v 0.27
I have changed all my require methods into imports.
Here's the error I receive:
I don't know if its relevant, but the first position of the error points to my LoginComp.js file which contains the following code:
/**
* Sample React Native App
* https://github.com/facebook/react-native
*/
'use strict';
import React, {
AppRegistry,
Component,
StyleSheet,
Text,
View,
Image,
TextInput,
Button,
TouchableHighlight
} from 'react-native';
class LoginComp extends Component {
constructor(){
super(props);
}
render() {
return (
<View style={{flex: 1}}>
<View style={this.props.styles.loginLogoContainer}>
<Image style={this.props.styles.view1logo} source={require('../imgs/Logo.png')} />
</View>
<View style={this.props.styles.loginContainer}>
<Text>Użytkownik:</Text>
<TextInput
style={this.props.styles.defaultInput}
placeholder="Użytkownik"
stretch={true}
autoComplete={false}
autoCorrect={false}
/>
<Text>Hasło:</Text>
<TextInput
style={this.props.styles.defaultInput}
placeholder="Hasło"
stretch={true}
autoComplete={false}
autoCorrect={false}
secureTextEntry={true}
/>
<TouchableHighlight onPress={this.props.LoginPress}>
<Text style={this.props.styles.loginButton}>Login</Text>
</TouchableHighlight>
</View>
<View style={this.props.styles.registrationWrapper}>
<Text>- lub -</Text>
<TouchableHighlight onPress={this.props.t_Registration}>
<Text style={this.props.styles.registration}>Załóż nowe konto</Text>
</TouchableHighlight>
</View>
</View>
);
}
}
module.exports = LoginComp;
Change your import statement like below and try.
import React, { Component } from 'react';
import {
AppRegistry,
StyleSheet,
Text,
View,
Image,
TextInput,
Button,
TouchableHighlight,
} from 'react-native';
Also constructor should be like below
constructor(props){
super(props);
}
I faced the same issue. Wrongly imported
import React, { Component } from "react-native";
instead of
import React, { Component } from "react";
see this answer https://stackoverflow.com/a/37676646/5367816
I hit this error when attempting to use:
class Leaderboard extends React.component {
}
It should have been Component with a capital C!
Personnaly, I solved this problem in another way:
I was importing a default module like import Module from "./path/to/Module.js".
But in the Module.js file, I ommited the default keyword:
export class Module {/*...*/} -> export default class Module {/*...*/}
Hope this will help someone. =)
just add the props in App.js file
type Props = {};
export default class App extends Component
May be latest version of expo/react native does not support #expo/react-native-action-sheet#2.5.0
upgrading #expo/react-native-action-sheet works for me:
yarn add #expo/react-native-action-sheet#latest

Resources