Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adding onViewableItemsChanged to SectionList changes the items passed to each section's keyExtractor #46588

Open
bhandanyan-nomad opened this issue Sep 20, 2024 · 2 comments
Labels
Component: SectionList Issue: Author Provided Repro This issue can be reproduced in Snack or an attached project.

Comments

@bhandanyan-nomad
Copy link

bhandanyan-nomad commented Sep 20, 2024

Description

We wrote a SectionList component where each section defines it's own keyExtractor. One of the sections uses a key from a nested object in each item in the section. It broke when we wanted to add visibility tracking to the section list, and it seems like the section objects are being run through the keyExtractor but only when onViewableItemsChanged prop is provided.

I expect that only items within each section should be run through the section's keyExtractor function, and that the behavior is consistent regardless of what props are provided.

Steps to reproduce

  1. Open expo snack linked below
  2. Run it on android or iOS device and observe it works
  3. Uncomment the onViewableItemsChanged line from the SectionList and observe the break

React Native Version

0.75.3

Affected Platforms

Runtime - Android, Runtime - iOS

Output of npx react-native info

See expo snack for reproduction

Stacktrace or Logs

Cannot read property 'id' of undefined

Reproducer

https://snack.expo.dev/V1Ad0VTld860Zdt8n-qb7

Screenshots and Videos

Screenshot 2024-09-20 at 5 07 04 PM
@softgenicsShubham
Copy link

@bhandanyan-nomad, I tried your reproducer, it needs slight modification.

import React from 'react';
import { View, Text, SafeAreaView, StyleSheet, SectionList, SectionListData } from 'react-native';

interface Item {
  id: string;
  title: string;
  nested?: {
    id: string;
  };
}

interface SectionData extends SectionListData<Item> {
  title: string;
  data: Item[];
}

const sections: SectionData[] = [
  {
    title: 'Active',
    data: [
      { id: '1', title: 'hello', nested: { id: '2' } },
      { id: '2', title: 'hello 2', nested: { id: '1' } },
    ],
  },
  {
    title: 'Closed',
    data: [
      { id: '4', title: 'hello', nested: { id: '3' } },
      { id: '3', title: 'hello 2', nested: { id: '4' } },
    ],
  },
];

interface ViewableItemsChangedProps {
  viewableItems: Array<{
    item: Item;
    key: string;
    isViewable: boolean;
    index: number | null;
    section?: SectionListData<Item>;
  }>;
}

const onViewableItemsChanged = ({ viewableItems }: ViewableItemsChangedProps) => {
  viewableItems.forEach(({ item }) => {
    // console.log({ item });
  });
};

export default function App() {
  return (
    <SafeAreaView style={styles.container}>
      <SectionList
        sections={sections}
        keyExtractor={(item) => {
          console.log('item', item)
          return item.nested?.id || item.id
        }}
        renderSectionHeader={({ section }) => (
          <View style={{ paddingVertical: 16 }}>
            <Text>{section.title}</Text>
          </View>
        )}
        renderItem={({ item }) => (
          <Text>Title: {item.title} NestedId: {item.nested?.id ?? 'No Nested ID'}</Text>
        )}
        onViewableItemsChanged={onViewableItemsChanged}
      />
    </SafeAreaView>
  );
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    justifyContent: 'center',
    backgroundColor: '#ecf0f1',
    padding: 8,
  },
});

@cortinico cortinico added Issue: Author Provided Repro This issue can be reproduced in Snack or an attached project. and removed Needs: Triage 🔍 labels Sep 23, 2024
@bhandanyan-nomad
Copy link
Author

@softgenicsShubham your code works but it doesn't really get at the root of the issue, which is that my code which runs fine without onViewableItemsChanged suddenly crashes as soon as it is provided. I'd like to figure out what's expected here and why. If it is expected that the sections are sent through the keyExtractor, I think the typescript types need to be updated to reflect that

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Component: SectionList Issue: Author Provided Repro This issue can be reproduced in Snack or an attached project.
Projects
None yet
Development

No branches or pull requests

4 participants