Search code examples
react-nativeflatlist

React Native - Navigate to detail screen by clicking on item in flatList?


I'm rendering names out of an API by using flatList. I'm then trying to make each item clickable and display more information about that person they clicked on, and i'm not sure how to go about things. Some posts i've read here on Stackoverflow that has links to examples are now dead and not useable.

I'm using DrawerNavigation and i will try my best to include the code needed, i have all my Screens in the app.js file.

App.js

export default function App() {
  return (
    <NavigationContainer>
      <Drawer.Navigator initialRouteName="Home" drawerPosition="right">
        <Drawer.Screen name="Home" component={HomeScreen} />
        <Drawer.Screen name="Players" component={PlayersScreen} />
      </Drawer.Navigator>
    </NavigationContainer>
 
  );
};

Each Screen has its own function bellow this, here is the PlayerScreen example which is the one containing the list rendered by flatList.

function PlayersScreen( { navigation } ) {
  const [isLoading, setLoading] = useState(true);
  const [data, setData] = useState([]);

  useEffect(() => {
  fetch('http://***.**.***.**:3000/players',
   { credentials: "same-origin",
   headers: {
    Accept: 'application/json',
    'Content-Type': 'application/json'
   },
  },
  )
    .then((response) => response.json())
    .then((json) => setData(json))
    .catch((error) => console.error(error))
    .finally(() => setLoading(false));
}, []);
  return (
      <View style={{marginTop: StatusBar.currentHeight}}>
      <TouchableOpacity onPress={() => navigation.dispatch(DrawerActions.toggleDrawer()) }>
            <Text>+</Text>
        </TouchableOpacity>

        <FlatList
            data={data}
            keyExtractor={({ id }, index) => id}
            renderItem={({ item }) => (
              <Text>{item.Name}</Text>
            )}
          />
      </View>
   
  );

---EDIT----

My flatlist currently look like this

  <FlatList
            data={data}
            keyExtractor={item => item.Name}
            renderItem={({ item }) => (
              <Text style={{fontSize: 32, color: 'white'}} onPress={() => alert("clicked")}>{item.Name}</Text>
            )}
          /> 

So now how do i handle that onPress to navigate to a component that will display more information about the name selected?

Any help is appreciated, cheers, N


Solution

  • First of all, it looks like you don't really want to navigate to the detail screen, but rather unfold a detail component which is residing in the same screen as the flatlist.

    If you really want to navigate to the detail screen, you'd have to pass a function with a call tonavigation.navigate to every item inside the renderItem property.

    Like this:

    <FlatList
     data={data}
     keyExtractor={({ id }, index) => id}
     renderItem={({ item }) => (
       <TouchableOpacity onPress={() => {
          navigation.navigate('ItemDetail', {data: item}
         }
       )}>
          <Text>
           +
          </Text>
       </TouchableOpacity>
    />
    

    If you want to pass a component, you'd have to do something like this:

    <FlatList
     data={data}
     keyExtractor={({ id }, index) => id}
     renderItem={({ item }) => (
       <ItemDetail item={item}/>    
      )}
    />
    

    and then handle the click on "+" inside your new ItemDetail component. Of cause you don't have to create a new component, you also can define all the markup inline, but it is cleaner and reusable if you use a new component.