Side menu drawer is not showing up, instead screen is rendering blank - reactjs

I am trying to create a side drawer only for one screen hence am using react-native-side-drawer as per the documentation in https://www.npmjs.com/package/react-native-side-drawer, however when I try to rerender it my screen is showing up blank as follows:
Below is my exact and complete code:
import React, {useEffect, useState} from 'react';
import {
View,
ScrollView,
ActivityIndicator,
Text,
TouchableOpacity,
StyleSheet,
Image,
} from 'react-native';
import MenuDrawer from 'react-native-side-drawer';
export default function HomeTabScreen(props) {
const {navigation} = props;
const [loading, setLoading] = useState(false);
// side drawer
const [open, setOpen] = useState(false);
useEffect(() => {
// console.log('useEffect - user', User);
// console.log('useEffect - mSChildId', mSChildId);
if (isValidObject(User) && isValidObject(mSChildId)) {
console.log('useEffect true');
console.log('useEffect true - user', User);
if (loadApi == true) {
getHomeTabMainAPI();
setLoadApi(false);
setSelectedChild(getChildFromUserChildrenList());
}
} else {
console.log('useEffect false');
if (!isValidObject(User) || !isValidObject(mSChildId)) {
console.log(
'!!!!!! Calling get user data !!!! Child Id ',
mSChildId,
' User Valid ',
isValidObject(User),
);
getUserData();
}
}
}, [User, mSChildId, loadApi]);
const toggleOpen = () => {
setOpen(!open);
};
const drawerContent = () => {
return (
<TouchableOpacity
style={{
marginLeft: '80%',
}}
onPress={() => logoutHandler()}>
<Text style={{fontSize: 15, fontWeight: 'bold', color: '#000'}}>
Log out
</Text>
</TouchableOpacity>
);
};
return (
<SafeAreaView
style={{flex: 1, justifyContent: 'center', alignItems: 'center'}}>
{loading ? (
<View style={{flex: 1, justifyContent: 'center', alignItems: 'center'}}>
<ActivityIndicator size="large" color="#FE017E" />
</View>
) : (
<ScrollView showsVerticalScrollIndicator={false}>
<View
style={{
flex: 1,
backgroundColor: '#fff',
flex: 1,
alignItems: 'center',
justifyContent: 'center',
}}>
<MenuDrawer
open={open}
drawerContent={drawerContent()}
drawerPercentage={45}
animationTime={250}
overlay={true}
opacity={0.4}>
<View
style={{
backgroundColor: '#fff',
padding: 10,
justifyContent: 'space-between',
flexDirection: 'row',
}}>
<TouchableOpacity onPress={() => toggleOpen()}>
<Icon size={15} name="bars" />
</TouchableOpacity>
<TouchableOpacity
style={{
marginLeft: '80%',
}}
onPress={() => logoutHandler()}>
<Text
style={{fontSize: 15, fontWeight: 'bold', color: '#000'}}>
Log out
</Text>
</TouchableOpacity>
</View>
<View>
renders more stuff here.....that should show up on the screen
</View>
</MenuDrawer>
</View>
</ScrollView>
)}
</SafeAreaView>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#fff',
alignItems: 'center',
justifyContent: 'center',
marginTop: 30,
zIndex: 0,
},
animatedBox: {
flex: 1,
backgroundColor: '#38C8EC',
padding: 10,
},
body: {
flex: 1,
alignItems: 'center',
justifyContent: 'center',
backgroundColor: '#F04812',
},
});
Any help would be appreciated, please let me know where I have gone wrong.
P.S: I am getting all the data on my console, but not on the screen

Related

How to update screen dimensions in react native

I have been trying to update my screen dimensions in react native so that the component resizes on-screen rotation with no vain. I have created my style in a separate file (Styles.js) and imported the styles in my login page like below:
Styles.js
import {
StyleSheet,
Dimensions
} from "react-native";
import {
scale,
ScaledSheet
} from "react-native-size-matters";
const styles = ScaledSheet.create({
scrollViewContainer: {
backgroundColor: '#E20030',
alignItems: 'center',
height: Dimensions.get('window').height,
padding: '50#s'
},
container2: {
alignItems: 'center',
justifyContent: 'center',
width: Dimensions.get('window').width,
flex: 1,
},
loginRect: {
borderRadius: '30#s',
marginTop: '20#s',
width: Dimensions.get('window').width * 0.8,
backgroundColor: 'white',
alignItems: 'center'
},
SectionStyle: {
flexDirection: 'row',
marginTop: 0,
marginLeft: '35#s',
marginRight: '35#s',
borderWidth: '1#s',
borderRadius: '5#s',
borderColor: '#dadae8',
},
});
Login.js
import React, { } from 'react';
import {
Text, View, TextInput, TouchableOpacity,
KeyboardAvoidingView,
} from 'react-native';
import { mystyles, styles } from './Components/styles';
const LoginScreen = () => {
return (
<View style={mystyles.scrollViewContainer}>
<KeyboardAvoidingView behavior="padding" style={{ flex: 100 }}>
<View style={mystyles.scrollViewContainer}>
<View style={mystyles.loginRect}>
<View style={{ flexDirection: 'row' }}>
<View style={{ flex: 1, marginLeft: 45, marginTop: 20 }}>
<Text style={{ color: 'black' }}>Username</Text>
</View>
</View>
<View style={styles.SectionStyle}>
<TextInput
style={styles.input}
/>
</View>
<View style={{ flexDirection: 'row' }}>
<View style={{ flex: 1, marginLeft: 45, marginTop: 20 }}>
<Text style={{ color: 'black' }}>Password</Text>
</View>
</View>
<View style={styles.SectionStyle}>
<TextInput
style={styles.input}
/>
</View>
<TouchableOpacity>
<Text style={styles.buttonTextStyle}>LOGIN</Text>
</TouchableOpacity>
</View>
</View>
</KeyboardAvoidingView>
</View>
)
}
export default LoginScreen;
So I have tried using Dimensions onchange listener in my Styles.js but I get an error
ERROR Error: Invalid hook call. Hooks can only be called inside of the body of a function component.
I created this function in the Styles.js file
m
function getDimensions() {
const [dimensions, setDimensions] = useState({
window,
screen
});
useEffect(() => {
const subscription = Dimensions.addEventListener(
"change",
({
window,
screen
}) => {
setDimensions({
window,
screen
});
console.log(dimensions.window.height + " +++ " + dimensions.screen)
}
);
// return () => subscription?.remove();
});
return dimensions.window;
}
Is there any way I can update the component sizes once the screen has been rotated?
This is working for me to detect rotation or changes in the size of the screen (split mode in tablets for example) without eventListeners.
import { Dimensions } from "react-native";
...
useEffect(() => {
...
}, [Dimensions.get("screen").height, Dimensions.get("screen").width]);
Hope this help to anybody

CustomDrawerNavigator: Change Active and Inactive Background Colour

On react-navigation/drawer's DrawerItem, is there a way to add active and inactive background colour? I followed this document to implement this https://reactnavigation.org/docs/drawer-navigator/.
I have added theses code lines to the drawerItems. But it won't work for me.
drawerContentOptions={{
activeTintColor: '#fff', /* font color for active screen label */
activeBackgroundColor: '#68f', /* bg color for active screen */
inactiveTintColor: 'grey', /* Font color for inactive screens' labels */
}}
initialized by the following,
import * as React from 'react';
import {
Button,
View,
Text,
StyleSheet,
TouchableOpacity,
Image,
} from 'react-native';
import { useDispatch, useSelector } from 'react-redux';
import {
createDrawerNavigator,
DrawerContentScrollView,
DrawerItem,
} from '#react-navigation/drawer';
import Home from '../home/containers';
import NavigationService from '../../navigation/NavigationService';
import * as homeActions from '../../features/home/actions';
import * as loginActions from '../../features/login/actions';
import { Images } from '../../config';
import i18n from 'i18n-js';
function HomeScreen({ navigation }) {
return (
<View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
<Button
onPress={() => NavigationService.navigate('Notifications')}
title="Go to notifications"
/>
</View>
);
}
function NotificationsScreen({ navigation }) {
return (
<View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
<Button onPress={() => NavigationService.goBack()} title="Go back home" />
</View>
);
}
function CustomDrawerContent({ props, navigation }) {
const dispatch = useDispatch();
const outlets = useSelector((state) => state.homeReducer.outlets);
const defaultOutLet = useSelector((state) => state.homeReducer.defaultOutLet);
const drawerItems = outlets.map((outlet) => {
return (
console.log("############## nav drawr ################## " + outlet.name),
<DrawerItem
{...props}
key={outlet.userCompanyId}
label={outlet.name}
onPress={() => {
dispatch(homeActions.changeSelectedOutlet(outlet));
navigation.closeDrawer();
}}
/>
);
});
return (
<View style={styles.flexView}>
<View style={styles.container}>
<Image
style={styles.image}
source={Images.icons.logo}
resizeMode="contain"
/>
{defaultOutLet && <Text style={styles.text}>{defaultOutLet.name}</Text>}
</View>
<View style={styles.separator} />
<View style={styles.flexView}>{drawerItems}</View>
<View style={styles.separator} />
<View style={styles.bottomView}>
<TouchableOpacity
style={styles.logoutContainer}
onPress={() => {
dispatch(homeActions.clearUserCompany());
dispatch(loginActions.completeLogOutClearingUserData());
}}>
<Image
style={styles.logoutIcon}
source={Images.icons.power}
resizeMode="center"
/>
<Text style={styles.logoutText}>{i18n.t('common.logout')}</Text>
</TouchableOpacity>
</View>
</View>
);
}
const Drawer = createDrawerNavigator();
export default function DrawerNavigator() {
return (
<Drawer.Navigator
drawerContent={(props) => <CustomDrawerContent {...props} />}
initialRouteName="Home">
<Drawer.Screen name="Home" component={Home} />
</Drawer.Navigator>
);
}
const styles = StyleSheet.create({
container: {
flex: 0.3,
width: '100%',
backgroundColor: 'white',
},
flexView: {
flex: 1,
},
text: {
marginVertical: 12,
color: 'black',
textAlign: 'center',
},
logoutContainer: {
flexDirection: 'row',
alignItems: 'center',
width: '100%',
},
logoutText: {
color: 'gray',
},
logoutIcon: {
flex: 0.4,
},
image: {
flex: 1,
marginTop: 20,
alignSelf: 'center',
},
separator: {
width: '100%',
height: 1,
backgroundColor: 'gray',
},
bottomView: {
flex: 0.15,
width: '100%',
justifyContent: 'center',
},
});

React how to show button over fullscreen video?

I have a fullscreen video iframe. I want show button over it. Is it possible? Z-index doesn't help.
A Modal allow to display a component on top of another and you can read more about it on this link (https://reactnative.dev/docs/modal).
import React, { useState } from "react";
import {
Alert,
Modal,
StyleSheet,
Text,
TouchableHighlight,
View
} from "react-native";
const App = () => {
const [modalVisible, setModalVisible] = useState(false);
return (
<View style={styles.centeredView}>
<Modal
animationType="slide"
transparent={true}
visible={modalVisible}
onRequestClose={() => {
Alert.alert("Modal has been closed.");
}}
>
<View style={styles.centeredView}>
<View style={styles.modalView}>
<Text style={styles.modalText}>Hello World!</Text>
<TouchableHighlight
style={{ ...styles.openButton, backgroundColor: "#2196F3" }}
onPress={() => {
setModalVisible(!modalVisible);
}}
>
<Text style={styles.textStyle}>Hide Modal</Text>
</TouchableHighlight>
</View>
</View>
</Modal>
<TouchableHighlight
style={styles.openButton}
onPress={() => {
setModalVisible(true);
}}
>
<Text style={styles.textStyle}>Show Modal</Text>
</TouchableHighlight>
</View>
);
};
const styles = StyleSheet.create({
centeredView: {
flex: 1,
justifyContent: "center",
alignItems: "center",
marginTop: 22
},
modalView: {
margin: 20,
backgroundColor: "white",
borderRadius: 20,
padding: 35,
alignItems: "center",
shadowColor: "#000",
shadowOffset: {
width: 0,
height: 2
},
shadowOpacity: 0.25,
shadowRadius: 3.84,
elevation: 5
},
openButton: {
backgroundColor: "#F194FF",
borderRadius: 20,
padding: 10,
elevation: 2
},
textStyle: {
color: "white",
fontWeight: "bold",
textAlign: "center"
},
modalText: {
marginBottom: 15,
textAlign: "center"
}
});
export default App;

React Native how to create a delete button that deletes a different element as well as itself

Look at my code below please I am trying to find a way to make a delete button but i am very new to react native, i have been trying to do it for the past few hours.
import React, { useState } from 'react';
import { StyleSheet, FlatList, Text, View, Image, TextInput, Button, Keyboard, TouchableOpacity, CheckBox } from 'react-native';
import Interactable from 'react-native-interactable';
export default function App()
const [enteredGoal, setEnteredGoal] = useState('');
const [courseGoals, setCourseGoals] = useState([]);
const goalInputHandler = (enteredText) => {
setEnteredGoal(enteredText);
};
const addGoalHandler = () => {
if (enteredGoal.length > 0) {
setCourseGoals(currentGoals => [...currentGoals, enteredGoal])
} else {
alert("You have to write something!")
}
}
return (
<View style={styles.container}>
<View style={styles.topPart}></View>
<View style={styles.navBar}>
<Image source={require('./assets/baseline_menu_black_18dp.png/')} />
<Text style={styles.heading}> Grocery List </Text>
</View>
<View style={styles.body}>
<TextInput
style={styles.textInput}
placeholder='Groceries'
maxLength={20}
onBlur={Keyboard.dismiss}
value={enteredGoal}
onChangeText={goalInputHandler}
/>
<View style={styles.inputContainer}>
<TouchableOpacity style={styles.saveButton}>
<Button title="ADD" onPress={addGoalHandler} color="#FFFFFF" style={styles.saveButtonText} />
</TouchableOpacity>
</View>
<View style={styles.container}>
<FlatList
data={courseGoals}
renderItem={itemData => (
<View style={styles.groceryItem} >
<Text style={styles.groceryItemText}>{itemData.item}</Text>
<Text style={styles.groceryItemDelete}>X</Text>
</View>
)}
/>
</View>
</View>
</View>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
},
topPart: {
height: '3%',
backgroundColor: '#5498A7',
},
navBar: {
height: '10%',
backgroundColor: '#5498A7',
elevation: 3,
paddingHorizontal: 15,
flexDirection: 'row',
alignItems: 'center',
},
body: {
backgroundColor: '#edebe9',
height: '100%',
flex: 1
},
heading: {
fontWeight: "bold",
justifyContent: 'center',
paddingLeft: '13%',
fontSize: 25,
color: '#d6d4d3'
},
textInput: {
borderColor: '#CCCCCC',
borderTopWidth: 1,
borderBottomWidth: 1,
height: 50,
fontSize: 25,
paddingLeft: 20,
paddingRight: 20
},
saveButton: {
borderWidth: 1,
borderColor: '#5498A7',
backgroundColor: '#5498A7',
padding: 15,
margin: 5,
},
saveButtonText: {
color: '#FFFFFF',
fontSize: 20,
textAlign: 'center'
},
groceryItem: {
borderWidth: 1,
borderColor: 'black',
backgroundColor: '#6A686B',
padding: 15,
margin: 5,
flex: 1,
flexDirection: 'row',
justifyContent: 'space-between'
},
groceryItemText: {
color: '#d6d4d3',
},
groceryItemDelete: {
color: 'red',
fontWeight: 'bold',
fontSize: 20
}
});
I hope you guys can find a solution I will keep u guys updated on my progress, I am constantly looking for answers but i don't really understand how to make the delete (X) work and to make it delete a different element, if you know a way to make work better just let me know i would appreciate it a lot
You have to send index to delete function.
renderItem={(itemData,index) => (
<View style={styles.groceryItem} >
<Text style={styles.groceryItemText}>{itemData.item}</Text>
<Text style={styles.groceryItemDelete.bind(index)}>X</Text>
</View>
and example delete function :
groceryItemDelete(index){
setCourseGoals(currentGoals.splice(index,1))
}
You need to implement the delete method and add an onPress event:
renderItem={(itemData, idx) => (
<View style={styles.groceryItem} >
<Text style={styles.groceryItemText}>{itemData.item}</Text>
<Text style={styles.groceryItemDelete} onPress={() => deleteItem(idx)}>X</Text>
</View>
)}
const deleteItem = idx => {
const clonedGoals = [...courseGoals]
clonedGoals.splice(idx, 1)
setCourseGoals(clonedGoals)
}

React Native Text Component not rendered

I am a newbie in react native. I tried to create a to-do app, simple enough. But I have no idea why the text in the created to-do item not rendered
import React, { useState } from 'react';
import {
StyleSheet,
Text,
View,
Button,
TextInput,
FlatList,
Dimensions
} from 'react-native';
export default function App() {
const [task, setTaskText] = useState('')
const [tasks, setTasks] = useState([])
const addTask = () => {
setTasks([...tasks, { key: Math.random().toString(), text: task}])
}
return (
<View style={styles.container}>
<View style={styles.form}>
<TextInput
onChangeText={setTaskText}
value={task}
placeholder="Type a task..."
style={styles.input}
multiline
/>
<Button title="Add Task" style={styles.button} onPress={addTask} />
</View>
<FlatList
style={styles.itemContainer}
data={tasks}
renderItem={itemData => (
<View style={styles.taskItem}>
<Text style={styles.taskText}>{itemData.text}</Text><Button title="Complete" />
</View>
)}
/>
</View>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
marginTop: 32,
backgroundColor: '#fff',
alignItems: 'center',
justifyContent: 'center',
},
form: {
// flex: 1,
flexDirection: 'row',
padding: 32,
justifyContent: 'space-between',
},
button: {
fontSize: 32,
padding: 5
},
tasks: {
flex: 1,
alignContent: 'flex-start',
},
input: {
flex: 1,
fontSize: 22,
},
itemContainer: {
flex: 1,
width: Dimensions.get('window').width,
padding: 20,
borderColor: 'red',
borderWidth: 1
},
taskItem: {
padding: 10,
borderColor: 'black',
borderWidth: 1,
backgroundColor: '#efefef',
marginBottom: 10,
alignContent: 'center',
justifyContent: 'center',
flexDirection: 'row'
},
taskText: {
flex: 1,
fontSize: 24,
borderColor: 'yellow',
borderWidth: 1,
color: 'black',
textAlign: 'left'
}
});
So I tried to use a flat list and gave some border color to pin point the component rendered. I could see that the text component was rendered but there is no content
Can anyone help? What went wrong?
Your implementation was wrong.
It should be renderItem({item, index, separators})
And for each of the item you should consume it like item.text
<FlatList
style={styles.itemContainer}
data={tasks}
renderItem={ ({item}) => (
<View style={styles.taskItem}>
<Text style={styles.taskText}>{item.text}</Text><Button title="Complete" />
</View>
)}
/>

Resources