getting the position of items inside React Native FlatList

1k Views Asked by At

Scenario:

I've got a number of items inside FlatList and I'm showing a Modal, with item coordinates, on long-pressing any of the Items and closing it when the touch is released.

I'm using Pressable for achieving long-press and onLayout to get the item coordinates.

Item component looks like this

const Item = ({ data, toggleModal }) => {
  const [layout, setLayout] = React.useState(null);
  return (
    <Pressable
      style={styles.item}
      delayLongPress={300}
      onLayout={({ nativeEvent }) => {
        setLayout(nativeEvent.layout);
      }}
      onLongPress={() => {
        toggleModal(layout);
      }}
      onPressOut={() => {
        toggleModal(null);
      }}>
      <Text style={styles.text}>{data}</Text>
    </Pressable>
  );
};

and the App component looks like this

// imports

export default function App() {
  const data = ['1', '2', '3', '4'];
  const [state, setState] = React.useState({
    visible: false,
    layout: { x: 0, y: 0, height: 0, width: 0 },
  });

  const toggleModal = (layout) => {
    setState((prevState) => ({
      ...prevState,
      visible: !prevState.visible,
      layout,
    }));
  };

  return (
    <View style={styles.container}>
      <FlatList
        data={data}
        keyExtractor={({ item }) => item}
        renderItem={({ item }) => (
          <Item data={item} toggleModal={toggleModal} />
        )}
      />
      <Modal visible={state.visible}>
        <Button title={'Close'} onPress={toggleModal} />
        <Text>
          layout: x:{state.layout?.x}, y:{state.layout?.y}, height:
          {state.layout?.height}, width:{state.layout?.width}
        </Text>
      </Modal>
    </View>
  );
}

But the coordinates of all the items are the same no matter which item I press.

If I use CellRendererComponent instead of renderItem I'm getting the correct coordinates but the Modal is not being closed.

CellRendererComponent={({ item }) => (
  <Item data={item} toggleModal={toggleModal} />
)}

Using ScrollView works fine though.

Here's the Expo Demo

0

There are 0 best solutions below