Tanya Dolgopolova
Tanya Dolgopolova

Reputation: 562

this.props in component does not contain navigation property

I want to navigate from one screen to another by this.props.navigation.navigate('Second Screen') but property 'navigation' does not contain in the props. Get error: Property 'navigation' does not exist on type 'Readonly<{}> & Readonly<{ children?: ReactNode; }>'


import React, { Component } from "react";

import styles from "./style";
import { Keyboard, Text, View, TextInput, TouchableWithoutFeedback, KeyboardAvoidingView } from 'react-native';
import { Button } from 'react-native-elements';

export default class SignInScreen extends Component {

  render() {
    return (
      <KeyboardAvoidingView style={styles.containerView} behavior="padding">


        <TouchableWithoutFeedback onPress={Keyboard.dismiss}>
          <View style={styles.loginScreenContainer}>
            <View style={styles.loginFormView}>
              <Text style={styles.logoText}>Book Market</Text>
              <TextInput placeholder="Email" placeholderTextColor="#c4c3cb" style={styles.loginFormTextInput} />
              <TextInput placeholder="Password" placeholderTextColor="#c4c3cb" style={styles.loginFormTextInput} secureTextEntry={true} />
              <Button
                buttonStyle={styles.loginButton}
                onPress={this.props.navigation.navigate('Home')}
                title="Login"
              />
            </View>
          </View>
        </TouchableWithoutFeedback>
      </KeyboardAvoidingView>
    );
  }
}

Upvotes: 1

Views: 1032

Answers (4)

Mohammad Sakhidel
Mohammad Sakhidel

Reputation: 106

I know this is an old question, but since the problem of undefined navigation property still exists at least for those who use EXPO managed approach, I'll write my solution hopefully it'll save someone's day.

After searching for hours I found no way to fix this bug and find a way to add navigation property to this.props. Finally, I solved the problem by using NavigationContext in this way:

<NavigationContainer>
    <NavigationContext.Provider>
        <Stack.Navigator>
            ...
        </Stack.Navigator>
    </NavigationContext.Provider>
</NavigationContainer>

Then get the navigation in a consumer:

<NavigationContext.Consumer>
    {navigation => {
        return (
            <Button onPress={() => this.onButtonPress(navigation)} />
        );
    }}
</NavigationContext.Consumer>

And finally:

onButtonPress(navigation) {
    try {

        navigation.navigate(RouteNames.FORGOTTEN_PASSWORD_SCREEN);

    } catch (e) {
        this.setState({ errors: [e.message] });
    }
}

Upvotes: 0

Tanya Dolgopolova
Tanya Dolgopolova

Reputation: 562

Okay, I find a solution. At first, I need to change extends of my class like

export default class SignInScreen extends Component<{navigation: any}>

Then change onPress action:

<Button
  buttonStyle={styles.loginButton}
  onPress={() => this.onSignInPress()}
  title="Login"
/>
private onSignInPress() {
    this.props.navigation.navigate('Home');
  }

Upvotes: 1

Diogo Aleixo
Diogo Aleixo

Reputation: 871

You can do what was already suggested, pass the navigation prop down to your target component

Ex:

<TargetComponent navigation={this.props.navigation} />

Or you can use withNavigation HOC from react-natigation.

Ex:

import {withNavigation} from 'react-navigation'

...

export default withNavigation(Child)

Hope it helps.

Upvotes: 1

Fakebounce
Fakebounce

Reputation: 707

You can only access it through the parent element. Pass navigation as a prop to its children to use it

Eg:

<Child navigation={this.props.navigation} />

Upvotes: 1

Related Questions