Undefined is not an object in react navigation props - android

Here this is my app.js
const AppStackNavigator = createStackNavigator({
Login:{ screen: Login },
DrawerNav: { screen: DrawerNavigator },
})
class App extends React.Component{
render() {
return (
<AppStackNavigator/>
)
}
}
export default createAppContainer(AppStackNavigator);
And this is DrawerNavigator.js file
class HomeScreen extends React.Component {
render() {
return (
<View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
<Header>
<Left>
<Icon name = "menu" onPress={() => this.props.navigation.openDrawer()}/>
</Left>
</Header>
<View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
<Button
title="Toggle"
onPress={() => this.props.navigation.toggleDrawer()}
/>
</View>
</View>
);
}
}
class SettingsScreen extends React.Component {
render() {
return (
<View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
<Button
title="Toggle Drawer"
onPress={() => this.props.navigation.toggleDrawer()}
/>
</View>
);
}
}
const CustomDrawerComponent = (props)=>(
<SafeAreaView>
<View style={{height:150, backgroundColor:'white', alignItems:'center', justifyContent:'center'}}>
<Image source={require('./logo.png')} style={{height:120, width:120, borderRadius:60}} />
</View>
<ScrollView>
<DrawerItems {...props} />
</ScrollView>
</SafeAreaView> )
const navigator = createDrawerNavigator({
HomeScreen: {
screen: HomeScreen,
navigationOptions: {drawerLabel: 'HomeScreen',}
},
SettingsScreen: {
screen: SettingsScreen,
navigationOptions: {drawerLabel: 'SettingsScreen',}
}},
{
drawerPosition :"left", contentComponent:CustomDrawerComponent
});
export default createAppContainer(navigator);
And this is login.js
class Login extends React.Component{
constructor(props){
super(props);
}
static navigationOptions = {
title:'Welcome',
headerLeft:
<View style={{paddingLeft:16}}>
<Icon
name="md-menu"
size={30}
color='black'
onPress={() => this.props.navigation.openDrawer()} />
</View>
}
loginHandler= ()=>{
//this.props.navigation.navigate('DrawerNav')
this.props.navigation.openDrawer()
}
render(){
return(
<View style={styles.container}>
<View style={{alignItems:'center'}}>
<Button
title={'Login'}
onPress={this.loginHandler.bind(this)}/>
</View>
</View>
)
}
}
export default Login;
Now Whenever i click icon to open navigation drawer then error arises undefined is not an object (evaluating _this2.props.navigation).I have tried many possible ways but i couldnt solve this problem.How can i solve this ? I have registered login component inside stack navigator then also login component was not able access navigation props.
onPress={() => this.props.navigation.openDrawer()}
Error describes that this line inside static block in login.js contains error

Related

null is not an object (evaluating '_this.drawer._root') using native base Drawer

I using the native-base library to create my app user interface, I make the native-base drawer and it's work correctly but when I move between component it gets an error for example when I move from Home screen to details screen and return to Home screen it gets an error like this null is not an object (evaluating '_this.drawer._root') from my details screen
Home.js file:
import React, { useEffect, useState } from 'react';
import * as Font from 'expo-font';
import { View, StyleSheet, ScrollView } from 'react-native';
import { NavigationContainer } from '#react-navigation/native';
import { Container, Header, Content, Spinner, Icon, Left, Right, Button, Body, Title, Drawer } from 'native-base';
import Product from './components/Product';
import SideBar from './components/SideBar';
function HomeScreen({ navigation, props }) {
const [isLoading, setLoading] = useState(true);
const [data, setData] = useState([]);
useEffect(() => {
fetch('https://boho-box.com/api/app')
.then((response) => response.json())
.then((json) => setData(json))
.catch((error) => console.error(error))
.finally(() => setLoading(false));
}, []);
closeDrawer = () => {
this.drawer._root.close()
};
openDrawer = () => {
this.drawer._root.open()
};
return (
<Container>
<Header
style={{ backgroundColor: '#8498a3' }}
androidStatusBarColor="#8498a3"
>
<Left>
<Button transparent>
<Icon name='arrow-back' />
</Button>
</Left>
<Body style={{alignItems: 'center', justifyContent: 'center', flex: 1}}>
<Title style={{alignItems: 'center', justifyContent: 'center'}} >Products</Title>
</Body>
<Right>
<Button
transparent
onPress={() => {
this.openDrawer()
}}
>
<Icon name='menu' />
</Button>
</Right>
</Header>
<Drawer
side='right'
ref={(ref) => { this.drawer = ref; }}
content={<SideBar />}
>
<Content>
{isLoading ?
<View style={{ flex: 1, flexDirection: 'row', justifyContent: 'center', padding: 24 }}>
<Spinner color='#8498a3' />
</View>
:
<ScrollView
style={{
flexGrow: 0,
width: "100%",
height: "100%",
}}>
{
data.map((product, index) => {
return(
<View style={styles.row} key={index}>
<View style={styles.col}>
<Product product={product}/>
</View>
</View>
)
})
}
</ScrollView>
}
</Content>
</Drawer>
</Container>
);
}
const styles = StyleSheet.create({
row: {
flex: 1,
flexDirection: 'row',
justifyContent: 'center',
},
col: {
flex: 1,
},
});
export default HomeScreen;
Details.js file:
import * as React from 'react';
import * as Font from 'expo-font';
import { View, Text, ScrollView } from 'react-native';
import { NavigationContainer } from '#react-navigation/native';
import { Container, Header, Content, Spinner, Left, Right, Button, Body, Title, Icon, Drawer } from 'native-base';
import Item from './components/Item';
import SideBar from './components/SideBar';
function DetailsScreen({ route, navigation, props }) {
const { name, price, img, text, productId } = route.params;
const detail = {
title: name,
price: price,
img: img,
text: text,
id: productId,
}
closeDrawer = () => {
this.drawer._root.close()
};
openDrawer = () => {
this.drawer._root.open()
};
return (
<Container>
<Header
style={{ backgroundColor: '#8498a3' }}
androidStatusBarColor="#8498a3"
>
<Left>
<Button transparent
onPress={() => {
navigation.goBack();
}}
>
<Icon name='arrow-back' />
</Button>
</Left>
<Body style={{alignItems: 'center', justifyContent: 'center', flex: 1}}>
<Title style={{alignItems: 'center', justifyContent: 'center'}} >Products</Title>
</Body>
<Right>
<Button transparent
onPress={() => {
this.openDrawer()
}}
>
<Icon name='menu' />
</Button>
</Right>
</Header>
<Drawer
side='right'
ref={(ref) => { this.drawer = ref; }}
content={<SideBar />}
>
<Content>
<ScrollView>
<Item pDetail={detail} />
</ScrollView>
</Content>
</Drawer>
</Container>
);
}
export default DetailsScreen;
Error screenshot when I want to return to Home screen:
I think the Home screen it's not rerender
react-native version: 0.63.2
native-base version: 2.15.2
react-native-cli version: 2.0.1
You are using a functional component, so you should use the 'useRef' hook for this
const drawer = useRef(null);
<Drawer
side='right'
ref={drawer}
content={<SideBar />}
>
The function should be like below
openDrawer = () => {
drawer.current._root.open()
};

Button on top of a Webview react native

Friends, I would like to overlay a button on a webview in react native to redirect routes manually.
The react native buttons should be invisible on top of the webview buttons
The following image shows the buttons on the web page and below the react native buttons.
1
another problem is that the keyboard does not open when clicking on an input within the webview
here's my code:
const App = () => {
const deviceHeight = Dimensions.get('window').height;
const deviceWidth = Dimensions.get('window').width
const [url, setUrl] = useState('https://rootroute.com.br/');
return (
<KeyboardAvoidingView
behavior={ Platform.OS === 'ios' ? 'padding' : undefined }
style={styles.keyboardAvoidingView}
>
<View style={{ flex: 1}}>
<WebView
source={{ uri: url }}
onError={syntheticEvent => {
const { nativeEvent } = syntheticEvent;
Alert.alert('WebView error: ', "" + nativeEvent);
}}
onHttpError={syntheticEvent => {
const { nativeEvent } = syntheticEvent;
console.warn(
'WebView received error status code: ',
nativeEvent.statusCode,
);
}}
mixedContentMode={'always'}
geolocationEnabled={true}
ignoreSslError={true}
javaScriptEnabled={true}
domStorageEnabled={true}
scalesPageToFit={true}
startInLoadingState={false}
style={{ flex: 1, width: deviceWidth, height: deviceHeight, marginTop: 15 }}
/>
<View style={styles.container}>
<View style={styles.buttonContainer}>
<Button
onPress={() => setUrl('https://rootroute.com.br/1')}
title="Home"
/>
</View>
<View style={styles.buttonContainer}>
<Button
onPress={() => setUrl('https://rootroute.com.br/2')}
title="Alerta"
/>
</View>
<View style={styles.buttonContainer}>
<Button
onPress={() => setUrl('https://rootroute.com.br/3')}
title="Explore"
/>
</View>
<View style={styles.buttonContainer}>
<Button
onPress={() => setUrl('https://rootroute.com.br/4')}
title="Carrinho"
/>
</View>
<View style={styles.buttonContainer}>
<Button
onPress={() => setUrl('https://rootroute.com.br/5')}
title="Conta"
/>
</View>
</View>
</View>
</KeyboardAvoidingView>
);
};
const styles = StyleSheet.create({
container: {
flexDirection: 'row',
alignItems: 'center',
justifyContent: 'center',
marginBottom: 50
},
buttonContainer: {
flex: 1,
},
keyboardAvoidingView: { flexGrow: 1, flexShrink: 1 },
});
export default App; ```
I think you don't need KeyboardAvoidingView in your case
Just use WebView and View
Because KeyboardAvoidingView use to handle TextInput keyboard on normal View

Native base drawer click navigating to root Screen with react-router-flux also not changing the Screen

I am using react-native app with react-router-flux navigation and native-base. Below are the versions-
"native-base": "^2.12.1",
"react": "16.8.3",
"react-native": "0.59.0",
"react-native-router-flux": "^4.0.6",
After clicking on Login button the screen move to home and from there I am opening the drawer which open it but navigate to login screen. Ideally it should be on the same page. Also I added the navigation from drawer it was not moving to a new screen which I remove later as first I have to solve this issue.
App.js
const RouterWithRedux = connect()(Router);
class AppNavigator extends Component<{}> {
static propTypes = {
drawerState: PropTypes.string
};
componentDidUpdate() {
if (this.props.drawerState === "opened") {
this.drawer._root.open();
}
if (this.props.drawerState === "closed") {
this.drawer._root.close();
}
}
openDrawer() {
this.drawer._root.open();
}
closeDrawer() {
if (this.props.drawerState === "opened") {
this.props.closeDrawer();
}
//this.drawer._root.close();
}
render() {
// eslint-disable-line class-methods-use-thisy
return (
<Drawer ref={(ref) => { this.drawer = ref; }}
content={<SideBar navigator={this.navigator} />}
onClose={() => this.closeDrawer()}
type="overlay"
tapToClose
tweenHandler={ratio => {
//eslint-disable-line
return {
drawer: { shadowRadius: ratio < 0.2 ? ratio * 5 * 5 : 5 },
main: {
opacity: (2 - ratio) / 2
}
};
}}
>
<StatusBar
backgroundColor={variables.brandPrimary}
barStyle="light-content"
/>
<RouterWithRedux>
<Scene key="root" hideNavBar>
<Scene key="login" component={Login} hideNavBar initial={true} />
<Scene key="signIn" component={SignIn} />
<Scene key="home" component={Home} />
<Scene key="register" component={Register} />
<Scene key="sideBar" component={SideBar} />
</Scene>
</RouterWithRedux>
</Drawer >
);
}
}
const bindAction = (dispatch) => {
return {
closeDrawer: () => dispatch(closeDrawer())
};
};
const mapStateToProps = state => ({
drawerState: state.drawer.drawerState
});
export default connect(
mapStateToProps,
bindAction
)(AppNavigator);
Login.js
class Login extends Component {
render() {
return (
<View style={{ flex: 1 }}>
<View style={{ padding: 10, marginBottom: 60 }}>
<Grid>
<Col style={{ padding: 10 }}>
<Button
onPress={() => Actions.signIn()}
transparent
block
style={styles.loginBtn}
>
<Text style={{ color: commonColor.brandPrimary, fontWeight: "600" }}>
SIGN IN
</Text>
</Button>
</Col>
<Col style={{ padding: 10 }}>
<Button
onPress={() => Actions.register()}
block
style={styles.registerBtn}
>
<Text style={{ fontWeight: "600", color: "#fff" }}>
REGISTER
</Text>
</Button>
</Col>
</Grid>
</View>
</View>
);
}
}
export default connect()(Login);
Home.js
class Home extends Component {
constructor(props) {
super(props);
}
render() {
return (
<View style={styles.container}>
<Text>Page under construuction</Text>
<View style={styles.headerContainer}>
<Header
iosStatusbar="default"
style={Platform.OS === "ios" ? styles.iosHeader : styles.aHeader}
androidStatusBarColor={commonColor.statusBarLight}
>
<Left>
<Button transparent onPress={this.props.openDrawer}>
<Icon
name="ios-menu"
style={{ color: commonColor.brandPrimary }}
/>
</Button>
</Left>
<Body>
<Title style={{ color: commonColor.brandPrimary, marginTop: -2 }}>
Drawer Demo App
</Title>
</Body>
<Right />
</Header>
</View>
</View>
);
}
}
function bindActions(dispatch) {
return {
openDrawer: () => dispatch(openDrawer())
};
}
const mapStateToProps = state => ({
navigation: state.cardNavigation
});
export default connect(
mapStateToProps,
bindActions
)(Home);

Creating Navigation Drawer with Image in header in React Native

import React, { Component } from 'react';
import { Alert, Button, TextInput, View, StyleSheet, Text, AsyncStorage } from 'react-native';
import { DrawerItems, DrawerNavigation } from 'react-navigation';
export default class Home extends Component {
const DrawerContent = (props) => (
<View>
<View
style={{
backgroundColor: '#f50057',
height: 140,
alignItems: 'center',
justifyContent: 'center',
}}
>
<Text style={{ color: 'white', fontSize: 30 }}>
Header
</Text>
</View>
<DrawerItems {...props} />
</View>
)
const Navigation = DrawerNavigator({
// ... your screens
Home:{
screen: HomeScreen,
},
Settings: {
screen: SettingsScreen,
},
}, {
// define customComponent here
contentComponent: DrawerContent,
})
render() {
return (
<View>
<Text>Welcome To Home</Text>
</View>
);
}
}
I am designing a screen which will be a home screen for my app. This screen will have navigation drawer like in Android and the drawer header will contain an image and a text label inside it and below that there will be drawer items from which i will navigate to a different screen. I have tried to achieve this using the above code but it doesn't work. Can you tell me where i am wrong? How can i achieve my target? I am a newbie to react native so i please make my concepts clear
Please replace your DrawerContent with the following code and check if it works.
const DrawerContent = (props) => {
return (
<SafeAreaView forceInset={{ top: 'always', horizontal: 'never' }}>
<View style={{ flexDirection: 'row', paddingBottom: 20 }}>
<View style={{ flex: 80, backgroundColor: '#f50057'}}>
<Image style={{ width: 181, height: 132}} source={images.logo} />
</View>
<Text style={{ color: '#000', fontSize: 30 }}>Header</Text>
</View>
<DrawerItems {...props}/>
</SafeAreaView>
)};
First create Drawer Component
export default class DrawerComponent extends React.Component {
render() {
return (
<SafeAreaView style={{ flex: 1 }}>
<ScrollView>
<View style={{ backgroundColor: "white" }}>
<Image
style={{ margin: 15 }}
source={{uri: 'https://facebook.github.io/react-native/docs/assets/favicon.png'}}
/>
</View>
<DrawerItems {...this.props} />
</ScrollView>
</SafeAreaView>
);
}
}
and import the component in your Home.js
import DrawerComponent from "./path/to/drawerComponent";
Please note : ScrollView is necessary for the case when you have more items to show ex: 7+ items (with margins in style prop) and also when screen height is small

React native drawer open issue

I'm trying to implement a drawer menu in react native and I'm not sure if I'm doing it right. Here is what I have so far:
#App.js
const RootStack = createStackNavigator(
{
Home: HomeScreen,
Details: DetailsScreen,
Save: SaveScreen,
About: AboutScreen,
},
{
initialRouteName: 'Home',
}
);
#Homescreen.js
static navigationOptions = {
// headerTitle instead of title
drawerLabel: 'Home',
headerTitle:
<View style={{flex: 1, flexDirection: 'row', marginLeft: 16}}>
<TouchableOpacity style={styles.button} onPress={()=>{this.props.navigation.openDrawer()}}>
<Image
source={require('../../assets/ic-hamburger.png')}
style={{ width: 20, height: 18 }}
/>
</TouchableOpacity>
<Text style={styles.menuTitle}>Menu</Text>
</View>
};
How come this.props.navigation is undefined here? How do I retrieve it so that the drawer opens when the image is clicked?
Thanks !
Try this using the navigation object:
static navigationOptions = ({ navigation }) => ({
// headerTitle instead of title
drawerLabel: 'Home',
headerTitle:
<View style={{flex: 1, flexDirection: 'row', marginLeft: 16}}>
<TouchableOpacity style={styles.button} onPress={()=>navigation.navigate('DrawerOpen')}>
....
</TouchableOpacity>
</View>
});

Categories

Resources