Agus Ryan
Agus Ryan

Reputation: 51

Cannot read property of 'navigate' of undefined

I am trying to make a stack navigator using reactstack navigation. When the button clicks, it appears on the detail screen only, the title of the page is detail. I am not yet to parsing data array to the next screen, it just tries to navigate the screen into the detail screen, and gets this error. I am new to react. Please help me solve this problem.

import React from 'react'
import {Button, StyleSheet, ScrollView, Text, View} from 'react-native'
import {useState, useEffect} from 'react'
import axios from 'axios'


const Item = ({id, user_id, title, onPress, navigation}) => {
  
    return (
        <View style={styles.container}>
            <Text style={styles.text}>Id :{id}
            </Text>
            <Text style={styles.text}>User Id :{user_id}
            </Text>
            <Text style={styles.text}>Tittle :{title}
            </Text>
            <View style={styles.container}>
                <Button onPress={() => navigation.navigate('Detail')} title='Detail'></Button>
            </View>
            <View style={styles.line}></View>
        </View>
    )

}


const Berita = () => {
    const [users,
        setUsers] = useState([]);


    useEffect(() => {
        getData();
    }, []);

    const selectItem = (item) => {
        console.log('Selected item: ', item)
    }

    const getData = () => {
        axios
            .get('https://gorest.co.in/public/v1/posts')
            .then(res => {
                console.log('res: ', res);
                setUsers(res.data.data);
            })
    }

    return (
        <ScrollView style={styles.container}>
            {users.map(user => {
                return <Item key={user.id} id={user.id} user_id={user.user_id} title={user.title}/>
            })}
        </ScrollView>

    )
}

export default Berita

const styles = StyleSheet.create({
    container: {
        padding: 15
    },
    text: {
        color: "black",
        marginTop: 5,
        fontStyle: 'italic',
        fontSize: 18,
        fontFamily: 'Arial'
    },
    line: {
        height: 1,
        backgroundColor: 'black',
        marginVertical: 20
    },
    title: {
        fontSize: 25,
        fontWeight: 'bold',
        textAlign: 'center',
        color: "black"
    },
    tombol: {
        padding: 10
    }

})

This is the stack screen navigator code

const Tab = createBottomTabNavigator();
const Stack = createStackNavigator();

const DetailBerita = () => {
    return (
        <Stack.Navigator >
            <Stack.Screen
                name='Berita'
                component={Berita}
                options={{
                headerTitleAlign: 'center'
            }}/>
            <Stack.Screen
                name="Detail"
                component={Detail}
                options={{
                headerTitleAlign: 'center'
            }}/>
        </Stack.Navigator>
    )
}

Upvotes: 2

Views: 2527

Answers (3)

Mashhad Rao
Mashhad Rao

Reputation: 1

A simple thing that worked for me, was making a new file and make sure that file name starts with Capital letter. The error I was facing was only due to my first letter of file being small. Here is code example:

<Stack.Navigator initialRouteName="Mainscreen">
   <Stack.Screen name="Mainscreen" component={Mainscreen} />
   <Stack.Screen name="Recipe" component={Recipe} />
</Stack.Navigator>

Mainscreen:

const Mainscreen= ({navigation}:any) => {        
     <Pressable onPress={()=>navigation.navigate('Recipe')

and it worked.

Upvotes: -1

ArnabXD
ArnabXD

Reputation: 520

This is happening because the navigation prop is passed to the Berita component and you are destructuring the property in Item component not in Berita.

So the code should look like

...
const Berita = ({ navigation }) => {

// ... 

  return (
    <ScrollView style={styles.container}>
      {users.map(user => {
        return (
          <Item
            key={user.id}
            id={user.id}
            user_id={user.user_id}
            title={user.title}
            navigation={navigation} // Pass navigation
          />
        );
      })}
    </ScrollView>
  );
};

Another way is - you can just use navigation in onPress (Berita) and pass down onPress to Item component

const Item = ({ id, user_id, title, onPress }) => {
  return (
    <View style={styles.container}>
      <Text style={styles.text}>Id :{id}</Text>
      <Text style={styles.text}>User Id :{user_id}</Text>
      <Text style={styles.text}>Tittle :{title}</Text>
      <View style={styles.container}>
        <Button onPress={onPress} title="Detail" />
      </View>
      <View style={styles.line}></View>
    </View>
  );
};

const Berita = ({ navigation }) => {
  const [users, setUsers] = useState([]);

  useEffect(() => {
    getData();
  }, []);

  const selectItem = item => {
    console.log('Selected item: ', item);
  };

  const getData = () => {
    axios.get('https://gorest.co.in/public/v1/posts').then(res => {
      console.log('res: ', res);
      setUsers(res.data.data);
    });
  };

  return (
    <ScrollView style={styles.container}>
      {users.map(user => {
        return (
          <Item
            key={user.id}
            id={user.id}
            user_id={user.user_id}
            title={user.title}
            onPress={() => navigation.navigate('Detail')}
          />
        );
      })}
    </ScrollView>
  );
};

Upvotes: 0

Julian Castro
Julian Castro

Reputation: 115

It appears that you are using Stack Navigators with different screen names, but you didn't send it. If possible, can you send that file, I would be able to help you a bit better. But from what I have I can try and explain how Stack navigation works. With this line of code:

navigation.navigate('Detail')

You specify that you want to navigate to the screen named "Detail", if you want to navigate to another screen then you can change it to the name of the screen. Let's say you want to navigate to your home screen, and its named "Home" in your Stack.Navigation component. Simply change your navigation to the following:

navigation.navigate('Home')

Upvotes: 0

Related Questions