Home > other >  React Native: pass onPress from renderItem to flatlist component
React Native: pass onPress from renderItem to flatlist component

Time:02-16

I'm having some issues handling a press on an item in a flatlist. I currently get an error Cannot read properties of undefined (reading 'onPressListHandler') when pressing on a list item.

Here's the code for my screen:

const listRenderItem = ({ item }) => {
    return (
        <Pressable onPress={() => this.onPressListHandler(item.id)} >
            <Text _dark={{ color: "warmGray.50" }} color="coolGray.800">
                {item.listName}
            </Text>
            <Icon as={Ionicons} name="chevron-forward-outline" size="sm" />
        </Pressable>
    )
};

const ListsList = () => {
    // ...
    function onPressListHandler(id) {
        navigation.navigate('ListDetailScreen', { listId: id })
    }
    // Render
    return (
        <FlatList
            data={lists}
            renderItem={listRenderItem}
            keyExtractor={item => item.id}
        />
    );

function MainScreen({ navigation }) {
    // ...
    // Render
    return (
            <ListsList />
    );
}

export default MainScreen;

How can I make sure the press event gets passed up and runs properly? TIA.

CodePudding user response:

There are multiple ways to achieve this, @yousoumar has a very valid approach.

Some others:

  1. Pass onPressListHandler to the component.
const onPressListHandler = (id) => {};

const renderItem = ({ item }) => listRenderItem(item, onPressHandler);

return (
  <FlatList
    renderItem={renderItem}
  />
)

// 
const listRenderItem = (item, onPress) => {
  // Now you can call onPress(item.id);
}

  1. Put listRenderItem inside of your ListsList component.

const ListsList = () => {
  const onPressListHandler = (id) => {};

  const listRenderItem = ({ item }) => {
    // You can call `onPressListHandler(item.id)` here.
  }

  return (
    <FlatList
      renderItem={listRenderItem}
    />
  )
}

I personally opt for the second option here but I am curious to understand why your render function is outside of your component.

CodePudding user response:

You could do it this way, by handling the redirection inside listRenderItem.

import { useNavigation } from '@react-navigation/native';

const listRenderItem = ({ item }) => {
    const {navigation} = useNavigation();
    return (
        <Pressable onPress={() =>  navigation.navigate('ListDetailScreen', { listId: item.id })} >
            <Text _dark={{ color: "warmGray.50" }} color="coolGray.800">
                {item.listName}
            </Text>
            <Icon as={Ionicons} name="chevron-forward-outline" size="sm" />
        </Pressable>
    )
};

const ListsList = () => {
    
    // Render
    return (
        <FlatList
            data={lists}
            renderItem={listRenderItem}
            keyExtractor={item => item.id}
        />
    );

function MainScreen({ navigation }) {
    // ...
    // Render
    return (
            <ListsList />
    );
}

export default MainScreen;
  • Related