Digvijay
Digvijay

Reputation: 3281

How to add clickable FlatList item and navigate to Detail component in React Native

I have a FlatList showing on main screen and on click of a FlatList item I want to navigate to the Detail component and pass related data to detail component.As I am new to react native I am struggling hard to implement this functionality though I have implemented FlatList on main screen.FlatList has been implemented under list.js component from this component I want to navigate to details.js component.

Below is my code:

App.js

import React from 'react';
import {StatusBar, StyleSheet} from 'react-native';
import { NavigationContainer } from '@react-navigation/native';
import { createStackNavigator } from '@react-navigation/stack';
import List from './components/list';
import Detail from './components/details';

const Stack = createStackNavigator();

const App = () => {

return (
  
  <NavigationContainer>
  <StatusBar barStyle="dark-content" backgroundColor="#8E24AA"/>
  <Stack.Navigator>
    <Stack.Screen 
    name="Home" 
    component={List}
    options={{ 
      headerStyle: {
        backgroundColor: '#AB47BC',
      },
      headerTintColor: '#fff' }} />

    <Stack.Screen 
    name="Detail" 
    component={Detail}
    options={{ 
      headerStyle: {
        backgroundColor: '#AB47BC',
      },
      headerTintColor: '#fff' }} />  
  </Stack.Navigator>
 </NavigationContainer>   

  ) 
}

export default App;

list.js

import React, {useEffect,useState} from 'react';
import {View,Text,StyleSheet,ActivityIndicator,FlatList} from 'react-native';

const List = () => {

 const[post,setPost] = useState([]);
 const[isLoading,setLoading] = useState(true);

 useEffect(() => {
    
    const url = 'http://api.duckduckgo.com/?q=simpsons+characters&format=json';
    fetch(url).then((res) => res.json())
    .then((resp) => {
        setPost(resp.RelatedTopics);
        setLoading(false);
    }).catch((err) => alert(err));
 },[]);

 const FlatListItemSeparator = () => {
  return (
   <View
    style={{  
      height: 0.7,
      width: "100%",
      backgroundColor: "#adadad"
     }}
   />
  );
}

    return(
 
       <View style={{flex:1,justifyContent:'center'}}>

        { isLoading ? <ActivityIndicator color="#8E24AA" size="large"/> : <FlatList 
            data = {post} 
            keyExtractor = {(item) => item.FirstURL} 
            renderItem = {({item}) => <Text style={styles.my}>{item.Text}</Text>} 
            ItemSeparatorComponent = { FlatListItemSeparator }/>  }
      
      </View>
    );
};

const styles = StyleSheet.create({
  my:{
     marginBottom: 15,
     marginTop: 15,
     marginLeft: 15
   }
});

export default List;

details.js

import React from 'react';
import {View,Text} from 'react-native';

const Detail = () => {

    return(
      <View>
          <Text>Hello there</Text>
      </View>
    );
};

export default Detail;

Someone let me know how can I implement desired functionality.

Upvotes: 0

Views: 648

Answers (3)

shammi
shammi

Reputation: 1419

firstly you need to get navigation prop on the list component

const List = ({navigation}) => { //<====

then you can use navigation and pass the data like this

 renderItem = {({item}) => <Text onPress={()=>navigation.navigate("Detail",{item})} style={styles.my}>{item.Text}</Text>} 

and get your data on Detail screen like this

import React from 'react';
import {View,Text} from 'react-native';

const Detail = ({route}) => {
    const {item}=route.params

    console.log("data is =>",item)
    return(
      <View>
          <Text>Hello there</Text>
      </View>
    );
};

export default Detail;

Upvotes: 1

Risina
Risina

Reputation: 244

You can add a TouchableOpacity, wrapping your Text component in renderItem. Add the function to onPress and then get the navigation prop and navigate to the Detail screen, passing the item. You can access these data through the route prop in the Detail screen.

    const handlePress = (item) => {
       navigation.navigate('Detail', item);
    }

    <TouchableOpacity onPress={() => {
      handlePress(item);
    }>
      <Text style={styles.my}>{item.Text}</Text>
    </TouchableOpacity>


In Detail, add the following code.

    const Detail = ({navigation, route}) => {
      const {Text} = route.params
      return (
        <View>
          <Text>{Text}</Text>
        </View>
      );
    };

Upvotes: 1

imKrishh
imKrishh

Reputation: 977

Each screen defined in Navigator receives a prop called navigation which has various methods to link to other screens.

  1. update the List component definition to use the prop navigation
const List = ({navigation}) => {
...

  1. use navigation.navigate to go to the Detail screen:
 //Add an onPress event handler 
 renderItem={({item}) => (
   <Text onPress={navigateToDetails} style={styles.my}>
    {item.Text}
   </Text>
 )}

Use navigation.navigate with Screen name defined in Stack.Navigator( ie Detail) to navigate to the Detail screen.

const navigateToDetails = () => {
  navigation.navigate('Detail');
};
  1. For passing params to Detail screen, put them in an object as a second parameter to the navigation.navigate function: navigation.navigate('RouteName', { /* params go here */ })

updating the onPress Function to pass item

  renderItem={({item}) => (
    <Text onPress={() => navigateToDetails(item)} style={styles.my}>
      {item.Text}
    </Text>
  )}

 // Update function definition to

  const navigateToDetails = item => {
    navigation.navigate('Detail', item);
  };
  1. To access the params in Detail screen, Read the params in your screen component: route.params
const Detail = ({navigation, route}) => {
  return (
    <View>
      <Text>Hello there {route.params.Text}</Text>
    </View>
  );
};

for more details on navigation: here

Upvotes: 1

Related Questions