react / react/react-native

SectionList scrollToLocation does not scroll to the correct position

オープン
#55,013 コメント 1 件 リアクション 0 件 担当者 0 名 GitHub で見る

まだ誰も着手していません。

Component: SectionList Needs: Triage :mag:
主要言語
C++
スター
127k
フォーク
25.3k
平均マージ
1日 23時間
マージ済み PR(30日)
4

説明

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

コントリビューションガイド

コントリビューションガイドを開く

はじめの一歩

  1. issue を最後まで読み、次にプロジェクトのコントリビューションガイドを読みます。
  2. 着手することを issue にコメントします — 二人が同じ作業をするのを防げます。
  3. リポジトリをフォークし、ブランチを切って変更します。
  4. issue 番号を参照したプルリクエストを送ります。

調査の方向性

リンクされたSnack reproducerをAndroidで実行し、SectionList.scrollToLocationと、提供されたgetItemLayoutの動作を比較します。まず、SectionList scrollToLocationエントリーポイントと、sectionIndexおよびitemIndexの処理を追跡します。完了の条件は、大規模なリストで要求されたセクションと項目が期待される位置に到達することです。

索引モデルが issue の本文から書いたものです。

評価

技術スタック
react-native, typescript
領域
mobile
issue の種類
バグ
難易度
4/5
見積もり時間
3〜5日
活発さ
静か
明瞭さ
おおむね明確
初心者へのやさしさ
45/100

新しい issue をメールで受け取る

初心者向けの GitHub issue を短くまとめたダイジェスト。