15

I have the following two pieces of code:

CustomHeader.tsx

import { View, StyleSheet, Button } from 'react-native';
import { NavigationScreenProps } from 'react-navigation';
import Icon from 'react-native-vector-icons/Ionicons';


export  const CustomHeader = ({ navigation }: NavigationScreenProps) => (
    <View style={[styles.container]}>
      <Icon
        name="md-menu"
        size={32}
        color="black"
        style={{ marginLeft: 10 }}
        onPress={() => navigation.openDrawer()}
      />
    </View>
  );

  const styles = StyleSheet.create({
    container: {
      borderBottomWidth: 2,
      height: 70,
      paddingTop: 20,
    },
  });

DetailScreen.tsx

import React from 'react';
import { Text, View, Button, Alert } from 'react-native';
import { NavigationScreenProps } from "react-navigation";
import { CustomHeader } from '../components/Header';

export class ChangeAccountDetailScreen extends React.Component {
  render() {
    return (
      <View style={{ flex: 1 }}>
        <CustomHeader navigation={this.props.navigation} />
        <Text style={{ fontSize: 20 }}>Profile Screen</Text>
      </View>
    );
  }
}

In detailscreen i get the following error:

Property 'navigation' does not exist on type 'Readonly<{}> & Readonly<{ children?: ReactNode; }>'.

I searched for the issue and i understand it has something the fact that i am not declaring a type in my CustomHeader. However i do not know how to solve this. I am kinda new to typescript. Could someone explain to me how to fix this type issue?

Niverhawk
  • 280
  • 1
  • 7
  • 15
  • 1
    What line causes that error? Btw, `type Props = NavigationScreenProps;` <--- you don't use your `Props` type anywhere, did you mean `extends React.Component`? – zerkms Apr 18 '19 at 01:06
  • Hi sorry I forgot to remove that line. I updated the code.. the line I get the error on is `````` and specifically on ```this.pros.navigation``` – Niverhawk Apr 18 '19 at 01:18
  • Did you try my suggested fix? – zerkms Apr 18 '19 at 01:21
  • Hey your suggested fix is what solved it!! Thank you very much. – Niverhawk Apr 18 '19 at 08:26
  • 1
    Does this answer your question? [Property 'value' does not exist on type 'Readonly<{}>'](https://stackoverflow.com/questions/47561848/property-value-does-not-exist-on-type-readonly) – Michael Freidgeim Aug 03 '20 at 23:03
  • Hi This is already a while ago but from what i can remember is that my solution looks like the answer in the link you sent. So yes! – Niverhawk Aug 05 '20 at 07:09

5 Answers5

20

I could be wrong, but have you tried adding navigation type to be expected

import React from 'react';
import { Text, View, Button, Alert } from 'react-native';
import { NavigationScreenProps } from "react-navigation";
import { CustomHeader } from '../components/Header';

interface Props {
  navigation: any
}

export class ChangeAccountDetailScreen extends React.Component<Props> {
  render() {
    return (
      <View style={{ flex: 1 }}>
        <CustomHeader navigation={this.props.navigation} />
        <Text style={{ fontSize: 20 }}>Profile Screen</Text>
      </View>
    );
  }
}
skube
  • 5,867
  • 9
  • 53
  • 77
  • Thanks for your answer. This is indeed how i have implemented the solution! – Niverhawk Aug 23 '19 at 10:23
  • 5
    For the interface definition, instead of "navigation: any;" you can also use "navigation: NavigationScreenProp;" to be more specific. You can find an example here https://dev.to/andreasbergqvist/react-navigation-with-typescript-29ka – Liem Dec 28 '19 at 11:10
8

Here is another solution where I add more details in the interface definition

import React from 'react';
import { Text, View, Button, Alert } from 'react-native';
import {
  NavigationParams,
  NavigationScreenProp,
  NavigationState
} from 'react-navigation';
import { CustomHeader } from '../components/Header';

interface Props {
  navigation: NavigationScreenProp<NavigationState, NavigationParams>
}

export class ChangeAccountDetailScreen extends React.Component<Props> {
  render() {
    return (
      <View style={{ flex: 1 }}>
        <CustomHeader navigation={this.props.navigation} />
        <Text style={{ fontSize: 20 }}>Profile Screen</Text>
      </View>
    );
  }
}
Liem
  • 730
  • 8
  • 15
6

More modern answer is to use useNavigation as explained in https://reactnavigation.org/docs/connecting-navigation-prop/

import * as React from 'react';
import { Button } from 'react-native';
import { useNavigation } from '@react-navigation/native';

function GoToButton({ screenName }) {
  const navigation = useNavigation();

  return (
    <Button
      title={`Go to ${screenName}`}
      onPress={() => navigation.navigate(screenName)}
    />
  );
}
Marco Bresciani
  • 142
  • 1
  • 10
  • best and simple ... but one more question what is the type of screenName ? how to pass down screen name ? – Ali Yar Khan Oct 28 '21 at 09:44
  • Screen name is a react component that is used for navigation. While studying, I've came up with this: https://github.com/marcoXbresciani/TKCompanionApp/tree/master/screens and you can take a look at how I managed navigation and screens. – Marco Bresciani Nov 04 '21 at 12:59
1
import React from 'react';
import { Button } from 'react-native';
import { withNavigation } from 'react-navigation';

class MyBackButton extends React.Component {
  render() {
    return <Button title="Back" onPress={() => { this.props.navigation.goBack() }} />;
  }
}

// withNavigation returns a component that wraps MyBackButton and passes in the
// navigation prop
export default withNavigation(MyBackButton);

https://reactnavigation.org/docs/en/connecting-navigation-prop.html

minjie li
  • 11
  • 1
1

Another way to solve this is to import ReactNode from react and tell the component it's type as ReactNode.

import React,{ReactNode} from 'react'

const GetStarted:ReactNode = ({navigation})=>{
return(
   <View> </View>
)
}