react / react/react-native

SectionList scrollToLocation does not scroll to the correct position

Offen
#55,013 1 Kommentar 0 Reaktionen 0 zugewiesene Personen Auf GitHub ansehen

Dieses Issue hat noch niemand übernommen.

Component: SectionList Needs: Triage :mag:
Vorherrschende Sprache
C++
Sterne
127k
Forks
25.3k
Ø Merge
1 T. 23 Std.
Gemergte PRs (30 T.)
4

Beschreibung

Description

When a SectionList contains a large number of items, calling scrollToLocation
scrolls to a slightly incorrect position, even though getItemLayout is properly provided.

Instead of scrolling exactly to the specified item, the list stops a bit offset from the expected location.

If this behavior is expected or if my usage of SectionList / getItemLayout is incorrect,
I would appreciate any guidance on the correct approach.

import React, { useRef, useMemo } from 'react';
import { SectionList, Text, View, Button } from 'react-native';

const HEADER_HEIGHT = 40;
const ITEM_HEIGHT = 30;

const TARGET_SECTION_INDEX = 20;

const generateSections = () => {
  const createItems = (prefix) => {
    const count = 20 + Math.floor(Math.random() * 100);
    return [...Array(count)].map((_, i) => ({
      label: `${prefix} Item ${i + 1}`,
    }));
  };

  return [...Array(24)].map((_, sectionIndex) => ({
    title: `Section ${sectionIndex + 1}`,
    data: createItems(`Section ${sectionIndex + 1}`),
  }));
};

export default function App() {
  const sectionListRef = useRef(null);
  const sections = useMemo(() => generateSections(), []);

  const scrollToSection = () => {
    if (sectionListRef.current) {
      sectionListRef.current.scrollToLocation({
        sectionIndex: TARGET_SECTION_INDEX,
        itemIndex: 0,
        viewPosition: 0,
      });
    }
  };

  return (
    <View style={{ flex: 1, paddingTop: 40 }}>
      <Button
        title={`Scroll to Section ${TARGET_SECTION_INDEX + 1}`}
        onPress={scrollToSection}
      />
      <SectionList
        ref={sectionListRef}
        sections={sections}
        keyExtractor={(item, index) => item.label + index}
        renderItem={({ item }) => (
          <View
            style={{
              height: ITEM_HEIGHT,
              justifyContent: 'center',
              borderBottomWidth: 1,
              borderColor: '#ccc',
            }}>
            <Text>{item.label}</Text>
          </View>
        )}
        renderSectionHeader={({ section: { title } }) => (
          <View
            style={{
              justifyContent: 'center',
              height: HEADER_HEIGHT,
              backgroundColor: '#eee',
            }}>
            <Text
              style={{
                fontWeight: 'bold',
              }}>
              {title}
            </Text>
          </View>
        )}
        getItemLayout={(_, index) => ({
          index,
          length: ITEM_HEIGHT,
          offset: ITEM_HEIGHT * index,
        })}
      />
    </View>
  );
}

Steps to reproduce
  1. Render a SectionList
  2. Call scrollToLocation with a valid sectionIndex and itemIndex
  3. Observe the scroll position
React Native Version

0.81.4

Affected Platforms

Other (please specify), Runtime - Android

Output of npx @react-native-community/cli info
skip
Stacktrace or Logs
nothing
MANDATORY Reproducer

https://snack.expo.dev/@kuroppi/sectionlist-scrolltolocation

Screenshots and Videos

expected:
Image

actual:
Image

Beitragsleitfaden

Beitragsleitfaden öffnen

Erste Schritte

  1. Lies das ganze Issue und danach den Beitragsleitfaden des Projekts.
  2. Schreib ins Issue, dass du es übernimmst — das erspart doppelte Arbeit.
  3. Forke das Repository und arbeite in einem Branch.
  4. Öffne einen Pull Request, der die Issue-Nummer nennt.

Rechercherichtung

Führe den verlinkten Snack-Reproducer auf Android aus und vergleiche SectionList.scrollToLocation mit dem bereitgestellten getItemLayout-Verhalten. Beginne damit, den SectionList scrollToLocation-Einstiegspunkt und die Verarbeitung von sectionIndex und itemIndex nachzuverfolgen. Als erledigt gilt, wenn der angeforderte Abschnitt und das angeforderte Element bei großen Listen die erwartete Position erreichen.

Vom Indexierungsmodell aus dem Issue-Text verfasst.

Bewertung

Tech-Stack
react-native, typescript
Bereich
mobile
Issue-Typ
Bug
Schwierigkeit
4/5
Geschätzter Aufwand
3-5 Tage
Aktivitätsstatus
Ruhig
Klarheit
Größtenteils klar
Anfängerfreundlichkeit
45/100

Neue Issues direkt in Ihr Postfach

Eine kurze Übersicht über anfängerfreundliche GitHub-Issues.