Too much space between the appbar and status bar - reactjs

I am making an app, where I want to use react navigation.
For some reason, whenever I use drawers in react navigation, there is a huge space between the status bar and the drawer app bar.
Here is my code for the ho -
import { StatusBar } from "expo-status-bar";
import * as React from "react";
import { useState, useEffect } from "react";
import { StyleSheet, Text, View, ScrollView } from "react-native";
import Constants from "expo-constants";
import Header from "../Header";
import { Flexbox } from "../Layout";
import Card from "../Card";
import { marginAboveCard } from "../../constants/constants";
import Row from "../Row";
import { convertToIndianNumberingFormat } from "../../utils/utils";
const HomeScreen = ({ navigation }) => {
const [cardsData, setCardsData] = useState({
confirmed: 0,
active: 0,
recovered: 0,
deceased: 0,
tests: 0,
critical: 0,
});
const [lastUpdated, setLastUpdated] = useState("");
useEffect(() => {
const getData = async () => {
const cardsDataResponse = await fetch(
"https://disease.sh/v3/covid-19/all"
);
const cardsDataFetched = await cardsDataResponse.json();
setCardsData({
confirmed: convertToIndianNumberingFormat(
cardsDataFetched.cases
),
active: convertToIndianNumberingFormat(cardsDataFetched.active),
recovered: convertToIndianNumberingFormat(
cardsDataFetched.recovered
),
deceased: convertToIndianNumberingFormat(
cardsDataFetched.deaths
),
tests: convertToIndianNumberingFormat(cardsDataFetched.tests),
critical: convertToIndianNumberingFormat(
cardsDataFetched.critical
),
});
const time = new Date(cardsDataFetched.updated);
const lastupdated = time.toLocaleTimeString();
setLastUpdated(`Last updated at ${lastupdated}`);
};
getData();
}, []);
return (
<ScrollView style={styles.main}>
<View style={{ marginTop: Constants.statusBarHeight }}>
<StatusBar style="auto" />
<Header text="COVID-19" />
<Text style={styles.lastUpdatedText}>{lastUpdated}</Text>
<View style={{ marginTop: marginAboveCard }}>
<Flexbox style={{ marginTop: 15 }}>
<Card
background="red"
title="Confirmed"
number={cardsData.confirmed}
/>
<Card
background="#3877F0"
title="Active"
number={cardsData.active}
/>
</Flexbox>
<Flexbox style={{ marginTop: marginAboveCard }}>
<Card
background="#47CC3C"
title="Recovered"
number={cardsData.recovered}
/>
<Card
background="#868686"
title="Deceased"
number={cardsData.deceased}
/>
</Flexbox>
<Flexbox style={{ marginTop: marginAboveCard }}>
<Card
background="#E85FEB"
title="Tests"
number={cardsData.tests}
/>
<Card
background="#5BF8B6"
title="Critical"
number={cardsData.critical}
/>
</Flexbox>
</View>
<View style={{ marginTop: 30 }}>
<Header text="TABLE STATISTICS" />
</View>
</View>
</ScrollView>
);
};
export default HomeScreen;
const styles = StyleSheet.create({
main: {
flex: 1,
backgroundColor: "#000232",
},
lastUpdatedText: {
color: "white",
textAlign: "center",
marginTop: 12,
fontSize: 15,
},
});
My app.jsx -
import * as React from "react";
import HomeScreen from "./components/screens/HomeScreen";
import VaccineScreen from "./components/screens/VaccineScreen";
import { NavigationContainer } from "#react-navigation/native";
import { createDrawerNavigator } from "#react-navigation/drawer";
const Drawer = createDrawerNavigator();
export default function App() {
return (
<NavigationContainer>
<Drawer.Navigator initialRouteName="Home">
<Drawer.Screen name="Home" component={HomeScreen} />
<Drawer.Screen name="Vaccine" component={VaccineScreen} />
</Drawer.Navigator>
</NavigationContainer>
);
}
If you look at the code of home screen properly, you would see a status style component which is set to auto. Even after removing it, the space is there. There are no errors in the console of any sort. This error started coming when I used react navigation drawer. Is there a way I can remove the space?

Did you try to move StatusBar as top most child like my sample below?
....
<View>
<StatusBar style="auto" />
<ScrollView style={styles.main}>
<View style={{ marginTop: Constants.statusBarHeight }}>
...
How you define the header title and the drawer icon?

Related

cannot read property 'map' of undefined react native

image errors
The error Cannot read property 'map' of undefined' is thrown when the map function in the Product component is executed.
I'm following the react Native tutorial, and I keep running into an issue when passing the value from the state of one component into another component.
I'm following the react Native tutorial, and I keep running into an issue when passing the value from the state of one component into another component.
i used axios to get the data
ProductScreen
import React, {useEffect, useState} from 'react';
import {View} from 'react-native';
import MenuProduct from '../components/Product/MenuProduct';
import MainHeader from '../components/Header/MainHeader';
import {POPULAR, Top_Sell} from '../data';
import ProductItem from '../components/Product/ProductItem';
import instance from '../routes/instance';
const ProductScreen = () => {
const [product, setProduct] = useState([]);
useEffect(() => {
const fetchData = async () => {
const data = await instance('/api/products', {
method: 'GET',
});
setProduct(data);
};
fetchData();
}, []);
return (
<View style={{flex: 1}}>
<MainHeader />
<MenuProduct list={Top_Sell} />
<ProductItem list={product} />
</View>
);
};
export default ProductScreen;
ProductItem
import React from 'react';
import ProductCard from './ProductCard';
const ProductItem = ({product}) => {
return (
<>
{product.map((item, index) => {
return (
<ProductCard
id={item._id}
image={item.image}
title={item.title}
price={item.price}
item={item}
key={index}
/>
);
})}
</>
);
};
export default ProductItem;
ProductCard
import React from 'react';
import {Image, ScrollView, Text, TouchableOpacity, View} from 'react-native';
import {colors, sizes, spacing} from '../../constants/theme';
import AddItem from '../../utils/AddItem';
const CardHeight = 220;
const ProductCard = ({props}) => {
return (
<ScrollView>
return (
<View
style={{
marginLeft: spacing.l,
marginBottom: spacing.l,
marginRight: spacing.l,
}}>
<View>
<View
style={{
backgroundColor: colors.white,
borderRadius: sizes.radius,
shadowColor: colors.black,
shadowRadius: 4,
shadowOpacity: 0.1,
shadowOffset: {width: 0, height: 2},
}}>
<TouchableOpacity
style={{
borderRadius: sizes.radius,
overflow: 'hidden',
flexDirection: 'row',
}}>
<Image
style={{
borderRadius: sizes.radius,
width: 160,
height: CardHeight - 60,
resizeMode: 'cover',
}}
source={props.image}
/>
<View style={{marginTop: spacing.l}}>
<View style={{marginLeft: spacing.l, marginBottom: spacing.s}}>
<Text style={{fontSize: 16, color: '#FA4A0C'}}>
{props.title}
</Text>
</View>
<View style={{marginLeft: spacing.l}}>
<Text style={{fontSize: 14, color: '#8b8989'}}>
{props.price}
</Text>
</View>
<TouchableOpacity style={{marginLeft: 130}}>
<AddItem />
</TouchableOpacity>
</View>
</TouchableOpacity>
</View>
</View>
</View>
); })
</ScrollView>
);
};
export default ProductCard;
I have tried several ways on stackoverflow but I can't figure it out
It should be list in ProductItem component and use list.map because when you sending prop in ProductItem you are sending list
import React from 'react';
import ProductCard from './ProductCard';
const ProductItem = ({list}) => {
return (
<>
{list.length > 0 && list.map((item, index) => {
return (
<ProductCard
id={item._id}
image={item.image}
title={item.title}
price={item.price}
item={item}
key={index}
/>
);
})}
</>
);
};
export default ProductItem;
Check the below syntax for passing data from parent to child component.
<Child parentToChild={data}/>
Here, we are passing the data in the child component as data.
data is the data we have to pass, and parentToChild is the prop's name.
Next, it's time to capture the data in the child component. And it's very simple.
Here, there can be two cases.
Case 1: If you are using a functional component, simply catch the parentToChild in the parameters.
import React from 'react'
export default function Child({parentToChild}) {
return (
<div>
{parentToChild}
</div>
)
}
Case 2: If you have a class component, then just use this.props.parentToChild.
import React, { Component } from 'react'
export default class Child extends Component {
render() {
return (
<div>
{this.props.parentToChild}
</div>
)
}
}

React native Navigation Stack Doesn't Work

I've problem about react native navigation. x
Everything seem run good. I don't see any problem terminal. Also I deleted this code
<Stack.Navigator>
<Stack.Screen name="Login" component={LoginScreen} />
</Stack.Navigator>
and I add this code
<Text>test message</Text>
my program work. you can see
But I add stack navigation code and I see blank page.can you see this picture
How can I solve this problem?
Full code from App.js
import { StatusBar } from 'expo-status-bar';
import { StyleSheet, Text, View} from 'react-native';
import Navigation from './views/navigation';
import ErrorScreen from './views/ErrorScreen/ErrorScreen';
export default function App() {
return (
<View style={styles.container}>
<Stack.Navigator>
<Stack.Screen name="Login" component={LoginScreen} />
</Stack.Navigator> </View>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#fff',
alignItems: 'center',
justifyContent: 'center',
},
});
Full code from LoginScreen.js
import { View, Text, Image, StyleSheet, useWindowDimensions, KeyboardAvoidingView} from 'react-native';
import React, {useState} from 'react'
import Logo from '../../assets/fdslogo.png';
import CustomInput from '../components/CustomInput/CustomInput';
import CustomButton from '../components/CustomButton/CustomButton';
import { useNavigation } from "#react-navigation/native";
const LoginScreen = () => {
const [email, setEmail] = useState('');
const [password, setPassword] = useState('');
const {height} = useWindowDimensions();
return (
<KeyboardAvoidingView behavior='padding'>
<View style={styles.root}>
<Image
source={Logo}
resizeMode="contain"
style={styles.logo}
/>
<CustomInput placeholder="E-Posta Adresinizi Giriniz"
value={email}
setValue={setEmail}/>
<CustomInput placeholder="Şifrenizi Giriniz"
value={password}
setValue={setPassword}
secureTextEntry/>
<CustomButton text="Giriş Yap" />
</View>
</KeyboardAvoidingView>
)
}
const styles = StyleSheet.create({
root: {
alignItems: 'center',
paddingTop: 0,
},
logo: {
maxWidth: 300,
maxHeight: 200,
},
});
export default LoginScreen;
I had the same issue.
What I did was to remove the view (in parallel the styles of the stylesheet) and it worked

React Native - React Navigation Cannot use Hooks in DrawerContent

I am developing an e-commerce application using React Native and I am trying to use useState in the drawerContent and it tells me this
Error: Invalid hook call. Hooks can only be called inside of the body
of a function component. This could happen for one of the following
reasons:
You might have mismatching versions of React and the renderer (such as React DOM)
You might be breaking the Rules of Hooks
You might have more than one copy of React in the same app
Thank you in advance for your answers.
Here's the code
import React, { useState } from 'react'
import { View, Text, TouchableOpacity, FlatList, StyleSheet, StatusBar } from 'react-native'
import IonIcons from "react-native-vector-icons/Ionicons"
import { categories } from '../../../services/DataTest'
import DrawerSearch from './DrawerSearch'
import DrawerItem from './DrawerItem'
export default function DrawerContent (props) {
const [search, setSearch] = useState("");
return (
<View>
<TouchableOpacity
style={styles.customDrawerTouch}
>
<View style={styles.backButtonRow}>
<IonIcons
name="ios-arrow-back"
size={25}
style={styles.customDrawerIcon}
color="#666666"
/>
<Text style={{ color: '#666666' }}>Back to Components</Text>
</View>
</TouchableOpacity>
<DrawerSearch value={search} setValue={setSearch}/>
<FlatList
data={categories}
keyExtractor={(item, index) => index.toString()}
renderItem={DrawerItem}
/>
</View>
);
}
const styles = StyleSheet.create({
customDrawerTouch: {
marginTop: StatusBar.currentHeight,
paddingLeft: 13,
paddingTop: 15,
},
customDrawerIcon: {
paddingRight: 10
},
backButtonRow: {
flexDirection: 'row',
alignItems: 'center',
paddingBottom: 17,
paddingLeft: 3,
borderBottomColor: '#F0F0F0',
borderBottomWidth: 1,
},
});
I'm using this component here
import * as React from 'react';
import { View, StyleSheet, StatusBar } from 'react-native';
import { createDrawerNavigator } from '#react-navigation/drawer';
import HeaderCategorie from '../../components/categories/index/HeaderCategorie';
import SearchBar from '../../components/home/index/SearchBar';
import DrawerContent from '../../components/categories/index/DrawerContent';
const Drawer = createDrawerNavigator();
function CategoriesScreen({ navigation }) {
return (
<View style={styles.container}>
<HeaderCategorie navigation={navigation}/>
<View style={styles.headerSearch}>
<SearchBar />
</View>
</View>
)
}
export default function Categories() {
return (
<Drawer.Navigator initialRouteName="Categories"
drawerContent={DrawerContent}
screenOptions={{headerShown:false}}
>
<Drawer.Screen name="Categories" component={CategoriesScreen} />
</Drawer.Navigator>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: "flex-start",
alignItems: "center",
marginTop: StatusBar.currentHeight,
},
headerSearch: {
marginVertical:10
},
headerSearchText: {
fontWeight:"bold",
fontSize:35,
marginLeft:20,
marginVertical:15,
}
});
Reason: By using drawerContent={DrawerContent}, you are actually passing the reference of the DrawerContent function, which ends up breaking rules of hooks.
So to resolve this, change the following line:
<Drawer.Navigator initialRouteName="Categories"
drawerContent={DrawerContent}
screenOptions={{headerShown:false}}
>
to this
<Drawer.Navigator initialRouteName="Categories"
drawerContent={(props)=> <DrawerContent {...props}/>} // here
screenOptions={{headerShown:false}}
>
demo snack

React Native Stack Navigator Use State

I try to make Share State Data From MyStack Component.
Components of Second Data is Always changed But First Screen is not
Could you tell me about what is problem of this??
And What do i have to Change.
thank you :D
import React ,{ useState } from 'react';
import { Button, View } from 'react-native';
import { NavigationContainer } from '#react-navigation/native';
import { createStackNavigator } from '#react-navigation/stack';
function First({route , navigation}) {
return (
<View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
<Button
title={route.params.count.toString()}
onPress={() => navigation.navigate('Second')}/>
</View>
);
}
function Second({route , navigation }) {
route.params.setCount(route.params.count + 1);
return (
<View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
<Button
title={route.params.count.toString()}
onPress={() => { navigation.goBack()}}
/>
</View>
);
}
const Stack = createStackNavigator();
function MyStack() {
const [count, setCount] = useState(0);
return (
<Stack.Navigator>
<Stack.Screen name="First" component={First} initialParams={{ count: count , setCount : setCount }}/>
<Stack.Screen name="Second" component={Second} initialParams={{ count: count ,setCount : setCount}}/>
</Stack.Navigator>
);
}
export default function App(props) {
return (
<NavigationContainer>
<MyStack props={props}/>
</NavigationContainer>
);
}
The reason for the above not working is the FirstScreen is not being re rendered. You cant dynamically change the intialparams after the screen is rendered.
Even your screen 2 is not working properly, you set it but you see the updated value when you revisit the screen.
The way to fix this is to use the context api which you can use to skip the navigation params.
And always use a hook like useEffect or a buttonclick to update the context otherwise it would keep rerendering which would result in an error.
The code would be like below.
import React, { useState, createContext, useContext } from 'react';
import { Button, View } from 'react-native';
import { NavigationContainer } from '#react-navigation/native';
import { createStackNavigator } from '#react-navigation/stack';
const appContext = createContext();
function First({ route, navigation }) {
const context = useContext(appContext);
return (
<View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
<Button
title={context.count.toString()}
onPress={() => navigation.navigate('Second')}
/>
</View>
);
}
function Second({ route, navigation }) {
const context = useContext(appContext);
return (
<View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
<Button
title={context.count.toString()}
onPress={() => {
navigation.goBack();
}}
/>
<Button
title="Add to Count"
onPress={() => {
context.setCount(context.count + 1);
}}
/>
</View>
);
}
const Stack = createStackNavigator();
function MyStack() {
const [count, setCount] = useState(0);
const state = { count, setCount };
return (
<appContext.Provider value={state}>
<Stack.Navigator>
<Stack.Screen name="First" component={First} />
<Stack.Screen name="Second" component={Second} />
</Stack.Navigator>
</appContext.Provider>
);
}
export default function App(props) {
return (
<NavigationContainer>
<MyStack props={props} />
</NavigationContainer>
);
}

React Navigation drawer goes blank after adding contentComponent

I am using React Navigation to create custom NavigationDrawer with a header on top this is how my code looks
import React, { Component } from "react";
import { View, Text, StyleSheet } from "react-native";
import AboutScreen from './modules/screens/About/index'
import ContactScreen from './modules/screens/Contact/index'
import HomeScreen from './modules/screens/Home/index'
import { createDrawerNavigator, DrawerItems } from "react-navigation";
import { Image, ScrollView, SafeAreaView, Dimensions } from 'react-native';
class NewDrawer extends Component {
render() {
return (
<AppDrawer />
);
}
}
const AppDrawer = createDrawerNavigator({
HomeScreen: HomeScreen,
AboutScreen: AboutScreen,
ContactScreen: ContactScreen,
},
//Commenting below part makes my code work
{
contentComponent: CustomDrawer
}
)
const CustomDrawer = (props) => (
<SafeAreaView style={{ flex: 1 }}>
<View style={{ height: 150, backgroundColor: 'white' }}>
<Image source={require('./modules/images/header.jpeg')}
style={{ height: 120, width: 120 }}>
</Image>
</View>
<ScrollView>
<DrawerItems {...props}>
</DrawerItems>
</ScrollView>
</SafeAreaView>
)
export default NewDrawer;
If I remove contentComponent i see my drawer items.
How can I get Header with custom drawer item?
I am using:-
npm > v6.4.1
Node > v8.12.0
react-navigation > v2.17.0
I am following this tutorial
You are not sending props to CustomDrawer . Try code below.
contentComponent: props => <CustomDrawer {...props} />
Drawer.js
<SafeAreaView style={{ flex: 1 }}>
<View style={{ height: 150, backgroundColor: 'white' }}>
<Image source={require('./modules/images/header.jpeg')}
style={{ height: 120, width: 120 }}>
</Image>
</View>
<ScrollView>
<DrawerItems {...props}>
</DrawerItems>
</ScrollView>
</SafeAreaView>
App.js
import CustomDrawer from './Drawer' // Import the file
const AppDrawer = createDrawerNavigator({
HomeScreen: HomeScreen,
AboutScreen: AboutScreen,
ContactScreen: ContactScreen,
},
{
contentComponent: <CustomDrawer />
}
)
This should work tested on android device

Resources