Drawer.Navigator Props not working on iOS - javascript

I'm just doing a course on React Native, and can't get any of the props to work using Drawer Navigator. I'm using iOS Simulator (14.3) on Mac M1, with WebStorm IDE. I'm also using bare React Native, not Expo.
I've attached my App.js code below. As you will see, it's very basic, but initialRouteName is the only prop that works. None of the others do what they are expected to do. The app doesn't crash, the props just don't change the behaviour as expected.
As far as I understand, these props are supported in iOS.
Can anyone help? Thanks in advance.
import React from 'react';
import { StyleSheet } from "react-native";
import { NavigationContainer } from "#react-navigation/native";
// screen code held in separate .js files
import ScreenA from "./ScreenA";
import ScreenB from "./ScreenB";
import { createDrawerNavigator } from "#react-navigation/drawer";
const Drawer = createDrawerNavigator();
function App() {
return(
<NavigationContainer>
<Drawer.Navigator
initialRouteName={'Screen B'} // works fine
drawerPosition={"right"} // not working
drawerType={'front'} // not working
edgeWidth={800} // not working
hideStatusBar={true} // not working
overlayColor={'#000000'} // not working
drawerStyle={{
backgroundColor: '#56cb6a' // not working
}}
>
<Drawer.Screen name={'Screen A'}
component={ScreenA}
/>
<Drawer.Screen name={'Screen B'}
component={ScreenB}
/>
</Drawer.Navigator>
</NavigationContainer>
)
}

UPDATE: I seem to have got this working using screenOptions instead of Drawer.Navigator props. Maybe Drawer.Navigator props have been deprecated since the tutorial?
screenOptions={{
drawerPosition: 'right',
drawerType: 'front',
swipeEdgeWidth: 200,
headerShown: false,
overlayColor: '#00000050',
drawerStyle: {
backgroundColor: '#dee0e8',
width: 225
},
swipeEnabled: true,
}}

Related

Is there a way to use a 'react-icon' with React Native?

Im actually writing a code in React native but while using react-icon I still don't know how to import an icon on my project.
I've tried with components such as Image but I don't see them on my Screen.
Please help me, below I share the code:
import { StyleSheet,Image, View, } from 'react-native';
import { AiOutlineHome } from 'react-icons/ai';
export function Navbar() {
return (
<View style={style.nav}>
<Image
style={style.navIcon}
source={<AiOutlineHome/>}
/>
</View>
)
}
const style = StyleSheet.create({
nav:{
width:'100%',
height:50,
position:'absolute',
top:702,
},
navIcon:{
color:'red',
resize:'cover'
}
})
react-icons is not designed to be used with React Native.
Try this library - https://github.com/oblador/react-native-vector-icons

React Native tabnavigation in seperate component?

I'm trying to make a RN-app, but I dont want to show the navigation on every screen. For example the registration and login screen shouldn't show the navigation. So I wanted to put the navigation in a component and import that component into the screens that should show it. I'm not sure if that works with navigation but I couldn't find anything saying that it won't work. I could be doing completely wrong.
The component I tried to create:
import React, { Component } from 'react'
import { createBottomTabNavigator } from '#react-navigation/bottom-tabs';
const Tab = createBottomTabNavigator();
class Navigation extends Component {
render() {
<Tab.Navigator>
<Tab.Screen name="Home" component={}/>
<Tab.Screen name="Explore" component={}/>
<Tab.Screen name="Account" component={}/>
</Tab.Navigator>
}
}
export default Navigation;
The way I wanted to import the component:
import React from 'react';
import { StyleSheet, Text, View } from 'react-native';
import { Navigation } from './components';
export default function App() {
return (
<View style={styles.container}>
<Navigation/>
</View>
);
}
I ever had the same issue. And this react navigation documentation is very helpful.
Please check here https://reactnavigation.org/docs/auth-flow/
If you just want keep the navigation and just need to hide the tab bar please read this one https://reactnavigation.org/docs/hiding-tabbar-in-screens

Lottie Animation JSON crashes my code with no explanation

I am working on an app, and am trying to implement a Lottie animation. For some reason, each time it starts the app it crashes, but when I use a normal loader animation that's built-in it works perfectly.
import LottieView from 'lottie-react-native';
import React from 'react';
import { View } from 'react-native';
import { globalStyles } from '../../../../theme/styles';
export const LottieAnimation = () =>{
return(
<View style={[globalStyles.center, globalStyles.horizontal]}>
<LottieView
style={{
width: 50,
height: 50,
}}
source={require('./49857-trodo-loader.json')}
/>
</View>
);
};
That's that function for the animation, and I can't find anything specifically wrong with it. Any ideas? The JSON is valid and everything. Any thoughts would be helpful.

React Native Expo error: Hooks can only be called inside the body of a function component

I am developing mobile app using React Native expo.. I am getting the following exception:
Invalid hook call. Hooks can only be called inside the body of a function component....
I have gone through the other answers posted here on SO and have confirmed that the hook in my code is indeed inside a function. But still I am unable to resolve the error. KIndly help. Please see my code below. Let me know if more clarification is needed.
import React, { useState, useEffect } from 'react';
import { SafeAreaView, StatusBar, Button, View, Platform , Text} from 'react-native';
import * as ImagePicker from 'expo-image-picker';
import Constants from 'expo-constants';
const statusBarPadding = Platform.OS === 'android' ? StatusBar.currentHeight: 0;
export default function OpenGallery () {
const [image, setImage] = useState(null);
useEffect(() => { // hook is inside function but still getting error
(async () => {
if (Platform.OS !== 'web') {
const { status } = await ImagePicker.requestMediaLibraryPermissionsAsync();
if (status !== 'granted') {
alert('Sorry, we need camera roll permissions to make this work!');
}
}
})();
}, []);
return (
<SafeAreaView style={{ paddingTop: statusBarPadding }}>
<Text> Some text </Text>
</SafeAreaView>
);
}
Second file:
import React from 'react';
import { SafeAreaView, StatusBar, Button, View, Platform , Text} from 'react-native';
import OpenGallery from './OpenGallery'
const statusBarPadding = Platform.OS === 'android' ? StatusBar.currentHeight: 0;
export default function CameraScreen() {
return (
<SafeAreaView style={{ paddingTop: statusBarPadding }}>
<Text> Upload image from gallery.</Text>
<Button title="Select from Gallery" onPress={OpenGallery} />
</SafeAreaView>
);
}
it is in fact not being called from inside the component. you are calling it from the JSX, which is entirely different. there are two issues here that break the rules of hooks.
hooks must be called unconditionally. you are breaking that rule here.
<Button title="Select from Gallery" **onPress={OpenGallery}** />
Hooks must be called from inside a functional component. you cannot import another component and call it as a function. this is what you're doing. you are calling the react component on a onPress method which is wrong.
What can you do to fix it?
bring the state down. make the check to see if it's on a web or a mobile in the second file itself. i would post the code but i don't have expo installed at the moment.
It might sound out of scope here but I think in your case, you need to specify the behaviour on how do you want the OpenGallery to appear after pressing the button on CameraScreen... you may be using navigation (may be react-navigation) or using a modal.
Let's say you're using react-navigation. (as you're using expo, it's normally included in the project) https://reactnavigation.org/
On CameraScreen
export default function CameraScreen({navigation}) {
const gotoOpenGallery = () => {
navigation.navigate('OpenGallery');
}
return (
<SafeAreaView style={{ paddingTop: statusBarPadding }}>
<Text> Upload image from gallery.</Text>
<Button title="Select from Gallery" onPress={gotoOpenGallery} />
</SafeAreaView>
);
}
You will also need to create a StackNavigator
Your App.js (or your entry point of the app)
import * as React from 'react';
import { View, Text } from 'react-native';
import { NavigationContainer } from '#react-navigation/native';
import { createStackNavigator } from '#react-navigation/stack';
import OpenGallery from './OpenGallery';
import CameraScreen from './CameraScreen';
const Stack = createStackNavigator();
function App() {
return (
<NavigationContainer>
<Stack.Navigator>
<Stack.Screen name="CameraScreen" component={CameraScreen} />
<Stack.Screen name="OpenGallery" component={OpenGallery} />
</Stack.Navigator>
</NavigationContainer>
);
}
export default App;

React Native: How to change/navigate the Screen as a Childcomponent?

Every little help is appreciated very much!
I got an Avatar as a Navigator, which should allow me to navigate through some screens! Some other Screens should be reached only by the my home screen. But when I press on the Button in the Avatar, nothing happens. I don't understand how and why, but I believe I made a mistake in the stackNavigator somewhere? Just to avoid any misunderstanding, the code below is shortened to avoid filling the page with unnecessary information, so it doesn't reflect 1:1 what you see in the screenshots.
Home Screen which should change
Avatar Screen through which I should be able to change the Home Screen
The goal is to be able to change which Screen is displayed in the <AppContainer/> through the <Avatar/> component below.
I tried with a onPress function inside the Avatar.js to call this.props.navigation.navigate("Agenda") but the screen didn't change. At least I got rid of the errors thanks to passing the navigation prop. I believe I made kind of a scrub mistake since i'm not experienced with react native, I hope some of the more experienced users can help me with that :) furthermore I don't think the screen itself is important to solve this, it's just a class component with panresponder and animated view.
import React from "react";
import { StyleSheet, View, StatusBar } from "react-native";
import { createAppContainer } from "react-navigation";
import { createStackNavigator } from "react-navigation-stack";
import Avatar from "../coreComponents/Avatar";
import ScHome from "../screens/ScHome";
import ScNewMedi from "../screens/ScNewMedi";
import ScCalendar from "./ScAgenda";
const AppStack = createStackNavigator(
{
Home: {
screen: ScHome,
},
Medis: {
screen: ScNewMedi,
},
Agenda: {
screen: ScCalendar,
},
},
{
headerMode: "screen",
initialRouteName: "Home",
backBehavior: "order",
}
);
const AppContainer = createAppContainer(AppStack);
export default class ScDefault extends React.Component {
render() {
return (
<View style={styles.container}>
<StatusBar
barStyle="light-content"
backgroundColor="transparent"
translucent
/>
<AppContainer />
<Avatar navigation={this.props.navigation} />
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
},
});
The problem is you are trying to access navigation outside the Appcontainer where the navigation is not available.
Easy fix :
Moving the Avatar component inside one of your main screens(ScHome,ScNewMedi,ScCalendar) then you will have access to navigation and everything will work as expected.
Workaround :
Let say the requirement is to have the Avatar outside the AppContainer then you have to use something like a navigation service.
The code would be as below
let _navigator;
const setTopLevelNavigator=(navigatorRef) =>{
_navigator = navigatorRef;
}
const navigate=(routeName, params) =>{
_navigator.dispatch(
NavigationActions.navigate({
routeName,
params,
})
);
}
//Change your app.js
return <View style={{flex:1}}>
<AppContainer
ref={navigatorRef => {
setTopLevelNavigator(navigatorRef);
}}
/>
<Avatar navigate={navigate} /></View>;
//Inside the Avatar onPress you can can do this
onPress={()=>this.props.navigate("Home")}
You can refer the docs for more details

Categories