React-Navigation this.props.navigation.navigate undefined is not an object - react-native

I am using react-navigation but my codes return ; this undefined is not an object (evaluating '_this2.props.navigation.navigate)
how can i fix this error?
myCodes;
import React, { Component } from 'react';
import Login from './components/LoginScreen/LoginScreen';
import AddNewUser from './components/AddNewUserScreen/AddNewUserScreen';
import { createStackNavigator } from 'react-navigation';
class App extends Component{
render(){
return(
<Login />
);
}
}
const RootStack = ({ createStackNavigator }) => (
{
Login: Login,
AddNew: AddNewUser,
});
export default App;
LoginScreen.js
<TouchableOpacity style={styles.ButtonContainer} onPress={()=> this.props.navigation.navigate('AddNew')}>
<Text style={styles.buttonText} >GİRİŞ</Text>
</TouchableOpacity>

You should start your app by calling RootStack like this:
class App extends Component{
render(){
return(
<RootStack />
);
}
}
also you can set initialRout in stack like this:
const RootStack = createStackNavigator({
Login: Login,
AddNew: AddNewUser,
}, { initialRouteName: 'Login'} )
Now, as you define, your app will start with login page and it has this.props.navigation by itself so you can use this.props.navigation.navigate('AddNew') without error.
But if you need to use navigation from a component, you have to send this.props.navigation from parent to component like this:
<YourComponent navigation={this.props.navigation}/>
Then you can use navigation in YourComponent component.
I hope this can help you

Related

React navigation drawer v5x useNavigation() with Component Class

I have tried many times to navigate using useNavigation() in my Component class. But I couldn't because according to the error I should use this method inside of a body function. I tried it inside render() method. It wasn't also helpful. Could you possibly help me if anyone knows?
import { useNavigation } from '#react-navigation/native';
export default class MenuDrawer extends React.Component{
render(){
const navigation = useNavigation();
return(
<View>
<Button onPress={()=>{navigation.navigate('detail')}} />
</View>
);
}
}
According to the docs here, you can wrap the component inside a function to use it
import { useNavigation } from '#react-navigation/native';
export default yourFunction(props) {
const navigation = useNavigation();
return <MenuDrawer navigation={navigation} />;
}
Your new MenuDrawer
export default class MenuDrawer extends React.Component {
render(){
const { navigation } = this.props;
return(
<View>
<Button onPress={()=>{navigation.navigate('detail')}} />
</View>
);
}
}

How to navigate to another screen from a function component?

I have a tabBarNavigation and i have a Home component. In the Home component i want to be able to navigate between two different screens. I have a component called ReadButton which when pressed should take me to another screen called 'BookScreen'. Now i have written so my HomeStack component have two screens 'HomeScreen' and 'BookScreen'. My problem is i cant make the 'ReadButton' to navigate to 'BookScreen' when pressed. It says ''Undefined is not an object(evaluating props.navigation.navigate).
...//This is in the main class provided by react
const HomeStack = createStackNavigator(
{
Home: HomeScreen,
Book: BookScreen,
},
config
);
const tabNavigator = createBottomTabNavigator({
HomeStack,
LinksStack,
SettingsStack,
});
tabNavigator.path = '';
export default tabNavigator;
...
//Below is the ReadButton class in a seperate file
import {withNavigation} from 'react-navigation'
const ReadButton = (props) => {
const [ReadPressed, setReadPressed] = useState(true)
const {navigate} = props.navigation.navigate
if(ReadPressed){
return(
<View>
<TouchableOpacity style={styles.buttonstyle} onPress={navigate("Home")}>
<Text style={styles.textstyle}> READ </Text>
</TouchableOpacity>
</View>
)
}
else {
return(
props.book
)
}
}
// Another class where i have my <ReadButton>
function BookCover(){
<TouchableOpacity style={styles.bottomFlexItemWhenClicked} onPress= .
{() => setBookCoverState(true)}>
<Text style={styles.BackgroundText}>{props.text}</Text>
<ReadButton book={props.book} navigation={props.navigation}>
</ReadButton>
</TouchableOpacity>)}
}
export default withNavigation(ReadButton);
Now i have tried putting 'Book: BookScreen' over 'Home: HomeScreen' and then the screen actually shows but i cant navigate between them. What am i missing?
Maybe you can try hooks?
install hooks: yarn add react-navigation-hooks#alpha
and then use it in your function component:
import { useNavigation } from 'react-navigation-hooks'
export default function Screen1 () {
const { navigate } = useNavigation()
return (
<Button
title='Try'
onPress={() => { navigate('Screen2') }}
/>
)
}
Please note that components inside the HomeScreen or BookScreen won't receive the navigation prop.
1.Either you send them manually like this
<ReadButton navigation={this.props.navigation}/>
or
2.Use the built in withNavigation of react-navigation like this
import {withNavigation} from 'react-navigation'
const ReadButton=(props)=>{}//Now you can access navigation prop here
export default withNavigation(ReadButton)
Second method will come to handy when your component is deeply nested and you want to access the navigation prop without manually passing the props.

Passing props from a root component through a BottomTabNavigator

My app root component looks like this:
export default class App extends React.Component {
render() {
<RootTabs doThings={this.doThings} />
}
}
The RootTabs component is created by createBottomTabNavigator from react-navigation:
const RootTabs = createBottomTabNavigator({
Movies: {
screen: Movies
},
Actors: ... // etc
})
My problem is, I would like to transmit data (as a prop if possible) from the root component (App) to the Movies component, but Movies do not receive the doThings prop.
How to transmit props through a BottomTabNavigator to children?
If that's not possible, what would be the most simple way for a children component to call a method on a root component, when they are separated by a BottomTabNavigator?
Try using screenProps
screenProps is documented on this page
Answered referred from here
Minimal Example would be
import React, { Component } from 'react'
import { AppRegistry, Button, Text, View } from 'react-native'
import { StackNavigator } from 'react-navigation'
class HomeScreen extends Component {
render() {
const { navigation, screenProps } = this.props
return (
<View>
<Text>Welcome, {screenProps.user.name}!</Text>
<Button onPress={() => navigation.navigate('Profile')} title="Go to Profile" />
</View>
)
}
}
class ProfileScreen extends Component {
render() {
const { navigation, screenProps } = this.props
return (
<View>
<Text>My Profile</Text>
<Text>Name: {screenProps.user.name}</Text>
<Text>Username: {screenProps.user.username}</Text>
<Text>Email: {screenProps.user.email}</Text>
<Button onPress={() => navigation.goBack()} title="Back to Home" />
</View>
)
}
}
const AppNavigator = StackNavigator({
Home: { screen: HomeScreen },
Profile: { screen: ProfileScreen },
})
class MyApp extends Component {
render() {
const screenProps = {
user: {
name: 'John Doe',
username: 'johndoe123',
email: 'john#doe.com',
},
}
return (
<AppNavigator screenProps={screenProps} />
)
}
}
export default MyApp
AppRegistry.registerComponent('MyApp', () => MyApp);
HomeScreen and ProfileScreen are components defined as screens for AppNavigator.
In the example above, I am passing the user data from the top-level, root component MyApp to both HomeScreen and ProfileScreen.
Since there is a AppNavigator between MyApp and the screen components, we will need to pass the user to screenProps prop of AppNavigator, so that the AppNavigator will pass it down to the screens. Any other prop except screenProps will not be passed down.
MyApp <-- user data here .
AppNavigator <-- the StackNavigator, the middle man. must use screenProps to pass user data down .
HomeScreen <-- will receive user data from this.props.screenProps.user instead of this.props.user .
ProfileScreen <-- same as HomeScreen

StackNavigator through Component gives undefined error

I was trying to use StackNavigator for navigation and it works when I use it to go from one screen to the other as explained here. But when I try to have a subcomponent to navigate through itself, the navigation doesn't seem to work and I couldn't find any solution to it.
As given in the code below, I'm trying to use the Test Component in which there is a button that can be clicked to move from HomeScreen to ChatScreen.
I'm pretty sure the solution is something basic, but I really can't find it anywhere.
Here's my code:
import React from 'react';
import {
AppRegistry,
Text,
View,
Button
} from 'react-native';
import { StackNavigator } from 'react-navigation';
class HomeScreen extends React.Component {
static navigationOptions = {
title: 'Welcome',
};
render() {
const { navigate } = this.props.navigation;
let userName = 'Ketan';
return (
<View>
<Text>Hello, Chat App!</Text>
<Button
onPress={() => navigate('Chat', { user: userName })}
title={"Chat with " + userName}
/>
<Test />
</View>
);
}
}
class ChatScreen extends React.Component {
static navigationOptions = ({ navigation }) => ({
title: `Chat with ${navigation.state.params.user}`,
});
render() {
const { params } = this.props.navigation.state;
return (
<View>
<Text>Chat with {params.user}</Text>
</View>
);
}
}
class Test extends React.Component {
render() {
const { navigate } = this.props.navigation;
return (
<View>
<Button
onPress={() => navigate('Chat', { user: 'TestBot' })}
title={'This is a test'}
/>
</View>
)
}
}
const NavApp = StackNavigator({
Home: { screen: HomeScreen },
Chat: { screen: ChatScreen },
});
AppRegistry.registerComponent('NavApp', () => NavApp);
Here's the error I'm getting:
Here's the demo to test: https://snack.expo.io/HyaT8qYob
I hope my question is clear enough of what I mean.
Since your Test component does not belong to navigation stack it doesn't have the navigation prop. You can do couple of things.
Simple one is to pass the navigation to the child component like the example below.
return (
<View>
<Text>Hello, Chat App!</Text>
<Button
onPress={() => navigate('Chat', { user: userName })}
title={"Chat with " + userName}
/>
<Test navigation={this.props.navigation} />
</View>
);
The second option is, you can use withNavigation from react-navigation. You can find more details about it here
import { Button } 'react-native';
import { withNavigation } from 'react-navigation';
const MyComponent = ({ to, navigation }) => (
<Button title={`navigate to ${to}`} onPress={() => navigation.navigate(to)} />
);
const MyComponentWithNavigation = withNavigation(MyComponent)
withNavigation
withNavigation is a higher order component which passes the
navigation prop into a wrapped component. It's useful when you
cannot pass the navigation prop into the component directly, or
don't want to pass it in case of a deeply nested child.

Cannot read property 'navigate' of Undefined in React Navigation

i'm React Native newbie. What i'm trying to do is added react navigation to my login page where user can click a button and navigate to the sign up page but i'm getting an error Cannot read property 'navigate' of Undefined. I've already searched the solution over an internet but no luck. This So does not help me - React Navigation - cannot read property 'navigate' of undefined and same with others .
Here is my code
index.ios.js
import React, { Component } from 'react';
import {
AppRegistry,
StyleSheet,
Text,
View
} from 'react-native';
import {StackNavigator} from 'react-navigation';
import Login from './src/screens/Login';
import Signup from './src/screens/Signup';
export default class tapak extends Component {
constructor(props) {
super(props);
this.buttonPress = this.buttonPress.bind(this);
}
render() {
return (
<View style={styles.container}>
<Text style={{color: 'blue'}} onPress={this.buttonPress}>sign up</Text>
</View>
);
}
buttonPress() {
console.log('called');
this.props.navigation.navigate('Signup');
}
}
const Stacks = StackNavigator({
Login: {
screen: Login
},
Signup:{
screen: Signup
}
});
Render the StackNavigator in your index.ios.js and move the button to the Login component:
const Stacks = StackNavigator({
Login: {
screen: Login
},
Signup:{
screen: Signup
}
});
class tapak extends Component {
render() {
return (
<Stacks />
);
}
}
Login.js :
export default class Login extends Component {
constructor(props) {
super(props);
this.buttonPress = this.buttonPress.bind(this);
}
buttonPress() {
console.log('called');
this.props.navigation.navigate('Signup');
}
render() {
return (
<View style={styles.container}>
<Text style={{color: 'blue'}} onPress={this.buttonPress}>sign up</Text>
</View>
);
}
}
Working example
here.
Write this code to index.ios.js
import React, { Component } from 'react';
import {
AppRegistry,
StyleSheet,
Text,
View
} from 'react-native';
import {StackNavigator} from 'react-navigation';
import Login from './src/screens/Login';
import Signup from './src/screens/Signup';
const Stacks = StackNavigator({
Login: {
screen: Login
},
Signup:{
screen: Signup
}
});
Login.js
import React ,{Component} from 'react';
import {
Text, View , Button,Image,
} from 'react-native';
export default class HomeScreen extends Component {
render() {
const { navigate } = this.props.navigation;
return (
<View>
<Text
onPress={() => navigate('Signup')}
> SignUp</Text>
</View>
);
}
}
Hope this help you.
I think you need to include navigationOptions, for example:
class MyComponent extends React.Component {
static navigationOptions = {
title: 'Great',
// other configurations
}
render() {
return (
// your view
)
}
}
Also yu need to make sure you use AppRegistry.registerComponent('glfm', () => Stacks); rather than AppRegistry.registerComponent('glfm', () => tapak);
The only answer to this question is to just put const { navigate } = this.props.navigation in your render() function and then you can use it in any component that you need
For Example
render() {
const { navigate } = this.props.navigation;
return (
<View>
<Text>This is the home screen of the app</Text>
<Button
onPress={() => navigate('Profile', { name: 'Brent' })}
title="Go to Brent's profile"
/>
</View>
);
}
Please read this doc for https://reactnavigation.org/docs/en/navigation-prop.html