Search code examples
javascriptreact-nativeparametersflatlistonpress

When i run this Error: TypeError: navigation.getParam is not a function:


i showing some value list description and images on home screen using Flatlist .when i onpress Flatlist item passing image source and id .value passing getparams but error was TypeError: navigation.getParam is not a function.why??. Please solve issue and edit my code . i am a new to react native please solve my issue.

import React from 'react';
import { StyleSheet, Text, View, FlatList, TouchableOpacity, Image } from 'react-native';
import { Card, Rating } from 'react-native-elements'
import { MaterialCommunityIcons } from '@expo/vector-icons';
import { dishesData } from './DishesData';

const MenuDetailScreen = ({ navigation }) => {

  const dish = dishesData.find(
    (dish) => dish.id === this.navigation.getParam('id')

  );

  return (
    <View style={styles.container}>
      <Card>
        <Card.Title
          style={styles.titleTextStyle}>{dish.title}</Card.Title>
        <Image style={{ height: 300, width: 350 }} source={{ uri: dish.imageSource }} />
      </Card>

      <Card>
        <View style={{ flexDirection: "row" }}>
          <Text style={styles.commentsTextStyle}>Comments</Text>
          <View style={{ flexGrow: 1 }} />
          <TouchableOpacity style={{ paddingBottom: 8 }} >
            <MaterialCommunityIcons name="pencil-circle" size={40} color="blue" />
          </TouchableOpacity>
        </View>
        <FlatList
          scrollEnabled={false}
          data={dish.dishDetails}
          keyExtractor={(item) => item.id.toString()}
          renderItem={({ item }) => {
            return (
              <View>
                <Text style={styles.headerTextStyle}>{item.comment}</Text>
                <Rating
                  readonly
                  imageSize={20}
                  startingValue={item.rating}
                  style={styles.ratingStyle}
                />
                <Text style={styles.spacing}>- {item.author} , {item.created_by}</Text>
              </View>
            );
          }}
        />
      </Card>
    </View>
  );
};

const styles = StyleSheet.create({
  container: {
    flex: 1,
    paddingBottom: 10
  },
  commentsTextStyle: {
    fontSize: 20,
    fontWeight: 'bold',
    textAlign: 'left'
  },
  textInputStyle: {
    width: "80%",
    padding: 8,
    marginBottom: 8,
    fontSize: 16
  },
  submitButtonStyle: {
    alignItems: 'center',
    width: "80%",
    borderRadius: 5,
    marginBottom: 8,
    padding: 8,
    fontWeight: 'bold',
    backgroundColor: 'rgba(0, 0, 255, 0.6)',
    color: 'black'
  },
  cancelButtonStyle: {
    alignItems: 'center',
    width: "80%",
    borderRadius: 5,
    marginBottom: 8,
    padding: 8,
    fontWeight: 'bold',
    backgroundColor: 'grey',
    color: 'black'
  },
  ratingStyle: {
    alignItems: 'flex-start',
    paddingBottom: 8
  },
  titleTextStyle: {
    fontSize: 20,
    textAlign: 'left'
  },
  textStyle: {
    paddingBottom: 8
  },
  headerTextStyle: {
    fontSize: 16,
    fontWeight: 'bold',
    paddingTop: 8
  },
  spacing: {
    padding: 8
  },
  ratingStyle: {
    alignItems: 'flex-start',
    paddingTop: 8
  }
});

export default MenuDetailScreen;

Error place

7 | const MenuDetailScreen = ({ navigation }) =>{
   8 | 
   9 |   const dish = dishesData.find(
> 10 |     (dish) => dish.id === this.navigation.getParam('id')
  11 |  
  12 |   );
  13 | 
enter code here

Solution

  • Better way is to useNavigation and useRoute from React Navigation.


    Step-by-step changes

    • Step 1
    import { useNavigation, useRoute } from '@react-navigation/native';
    
    • Step 2
    const navigation = useNavigation();
    const route = useRoute();
    
    • Step 3
    const { id } = route.params
    
    • Step 4 - Check if you are passing params when you navigate

      Example)

      onPress={() => navigation.navigate('SCREEN_NAME_HERE', {
         PARAM_KEY: PARAM_VALUE
      })}
      

    Full Example

    import React from 'react';
    ...
    import { useNavigation, useRoute } from '@react-navigation/native';
    
    /*
    Navigate to this screen by
    navigation.navigate('MenuDetailScreen', {
       id: <ID_VALUE_HERE>
    })
    */
    const MenuDetailScreen = () => {
      const navigation = useNavigation();
      const route = useRoute();
      const { id } = route.params
    
      const dish = dishesData.find(
        (dish) => dish.id === id
      );
    
      return (
        ...
      )
    }
    

    Once you get it working, I recommend you to go over Type checking with TypeScript for safely navigating between screens in React.