【React Native】FlatList.getNativeScrollRef()でよくあるエラーと解決策
FlatList.getNativeScrollRef()
は、React NativeのFlatList
コンポーネントが内部的に使用しているネイティブのスクロールコンポーネント(例えば、iOSではUIScrollView
、Androidではandroid.widget.ScrollView
など)への参照(ref)を取得するためのメソッドです。
なぜこれが必要なのか?
通常、React Nativeではコンポーネントを操作するためにRefを使用しますが、FlatList
は内部的に多くの最適化を行っており、直接ScrollView
のようなネイティブのスクロールコンポーネントを公開しているわけではありません。
しかし、アニメーションライブラリ(例: react-native-reanimated
)など、より低レベルなネイティブのスクロール操作を行いたい場合に、このネイティブなスクロールコンポーネントへの直接的な参照が必要になることがあります。getNativeScrollRef()
メソッドは、このような場合に、基盤となるネイティブスクロールコンポーネントへのアクセスを提供します。
使い方
FlatList
のRefを介して呼び出すことができます。
import React, { useRef, useEffect } from 'react';
import { FlatList, Text, View } from 'react-native';
const MyList = () => {
const flatListRef = useRef(null);
const data = Array.from({ length: 50 }, (_, i) => ({ id: String(i), title: `Item ${i}` }));
useEffect(() => {
if (flatListRef.current) {
// getNativeScrollRef() を使ってネイティブのスクロールリファレンスを取得
const nativeScrollRef = flatListRef.current.getNativeScrollRef();
console.log('ネイティブスクロールRef:', nativeScrollRef);
// ここで nativeScrollRef を使って、特定のネイティブ操作を行うことができる(上級者向け)
// 例: react-native-reanimated の scrollTo など
}
}, []);
return (
<FlatList
ref={flatListRef}
data={data}
renderItem={({ item }) => (
<View style={{ padding: 20, borderBottomWidth: 1, borderColor: '#ccc' }}>
<Text>{item.title}</Text>
</View>
)}
keyExtractor={(item) => item.id}
/>
);
};
export default MyList;
上記の例では、useRef
を使ってFlatList
コンポーネントへの参照を作成し、useEffect
内でgetNativeScrollRef()
を呼び出してネイティブのスクロールリファレンスを取得しています。
注意点
- アニメーションライブラリとの連携:
react-native-reanimated
などのアニメーションライブラリでスクロール操作をより細かく制御したい場合に、このメソッドが役立つことがあります。例えば、react-native-reanimated
のscrollTo
関数は、このネイティブスクロールRefを引数として受け取ることがあります。 - プラットフォーム依存: 取得されるネイティブのスクロールリファレンスは、iOSやAndroidといったプラットフォームによって異なる型を持ちます。
- 低レベルなAPI:
getNativeScrollRef()
は、通常の使用ではほとんど必要ありません。FlatList
が提供するscrollToIndex
やscrollToOffset
などの高レベルなメソッドで事足りることがほとんどです。
flatListRef.current が null または undefined になる
エラーの状況:
flatListRef.current.getNativeScrollRef()
を呼び出そうとした際に、「Cannot read property 'getNativeScrollRef' of null (or undefined)」のようなエラーが発生する。
原因:
FlatList
コンポーネントがまだマウントされていないか、Refが正しく設定されていない可能性があります。FlatList
コンポーネントが実際にレンダリングされる前に、Refが参照可能になる前にメソッドを呼び出そうとしていることがよくあります。
トラブルシューティング:
- 条件付きレンダリング:
FlatList
が条件付きでレンダリングされる場合(例: データがロードされるまで表示されないなど)は、flatListRef.current
がnull
でないことを必ず確認してからアクセスしてください。 useEffect
の使用と依存関係:getNativeScrollRef()
を呼び出す際は、FlatList
がレンダリングされてRefがセットされた後に実行されるように、useEffect
フックを使用し、依存関係にflatListRef
(または関連する状態)を含めるようにしてください。import React, { useRef, useEffect } from 'react'; import { FlatList } from 'react-native'; const MyList = () => { const flatListRef = useRef(null); useEffect(() => { if (flatListRef.current) { const nativeScrollRef = flatListRef.current.getNativeScrollRef(); console.log('ネイティブスクロールRef:', nativeScrollRef); } }, [flatListRef.current]); // flatListRef.current が変更されたときに実行 // または、コンポーネントがマウントされた後に一度だけ実行したい場合は空の配列 `[]` // しかし、もし FlatList が条件付きでレンダリングされる場合などは、ref.currentのチェックが必須です return ( <FlatList ref={flatListRef} data={/* ... */} renderItem={/* ... */} keyExtractor={/* ... */} /> ); };
getNativeScrollRef が関数ではないというエラー
エラーの状況:
「flatListRef.current.getNativeScrollRef is not a function
」のようなエラーが発生する。
原因: これは通常、以下のいずれかの理由で発生します。
ScrollView
のRefを取得しようとしている:FlatList
ではなく、内部のScrollView
のRefを直接取得しようとしていると、このようなエラーになる場合があります。- 誤ったRefの対象:
FlatList
以外のコンポーネントのRefに対してgetNativeScrollRef()
を呼び出している可能性があります。 - 古いReact Nativeバージョン:
getNativeScrollRef()
は比較的新しい機能です。古いReact Nativeのバージョンを使用している場合、このメソッドが存在しない可能性があります。
トラブルシューティング:
FlatList
のRefであることを確認: 意図的にScrollView
などのRefを取得しているわけではないことを確認してください。getNativeScrollRef()
はFlatList
に特化したメソッドです。- Refが正しいコンポーネントにアタッチされているか確認:
ref={flatListRef}
が正しくFlatList
コンポーネントにアタッチされているか再確認してください。 - React Nativeのバージョン確認: 使用しているReact Nativeのバージョンが、
getNativeScrollRef()
をサポートしているか確認してください。最新のReact Nativeにアップデートすることを検討してください。
ネイティブのスクロールリファレンスが期待通りに機能しない
エラーの状況:
getNativeScrollRef()
で取得したネイティブのリファレンスを使って、アニメーションライブラリなどでスクロール操作を試みても、何も起こらないか、予期しない動作をする。
原因:
FlatList
の最適化の影響:FlatList
はパフォーマンスのために多くの最適化(仮想化など)を行っています。これらの最適化が、ネイティブレベルでの直接的なスクロール操作に影響を与える可能性があります。- アニメーションライブラリのバージョンの不一致: 使用しているアニメーションライブラリ(例:
react-native-reanimated
)が、React NativeやFlatList
の特定のバージョンと互換性がない場合があります。 - 間違ったネイティブ操作: 取得したネイティブリファレンスに対する操作が、そのプラットフォームのネイティブコンポーネントで期待される動作と一致していない可能性があります。
- 非同期性: ネイティブのリファレンスに対する操作は非同期である場合があります。
トラブルシューティング:
FlatList
の標準メソッドの使用検討: 多くのスクロール操作は、FlatList
自体が提供するscrollToIndex
やscrollToOffset
などのメソッドで実現できます。これらの高レベルなAPIで目的が達成できる場合は、getNativeScrollRef()
を使う必要がないかもしれません。- シンプルなケースで試す: まずは
FlatList
以外の簡単なScrollView
でネイティブスクロール操作が機能するかどうかをテストし、問題がFlatList
に固有のものか、それともネイティブ操作全般に関するものかを切り分けてください。 - デバッグログの出力: 取得した
nativeScrollRef
の内容をconsole.log()
で出力し、どのようなオブジェクトが返されているかを確認してください。プラットフォーム(iOS/Android)によって異なる可能性があります。 - アニメーションライブラリのドキュメント参照:
react-native-reanimated
などのライブラリを使用している場合は、そのライブラリのドキュメントを詳しく参照し、getNativeScrollRef()
から取得した参照をどのように使用すべきか確認してください。特定のプロパティやメソッドにアクセスする必要があるかもしれません。 - 非同期操作の考慮: ネイティブの操作が非同期である可能性があるため、操作の完了を待つ必要がある場合があります。
Androidで問題が発生する (特にreact-native-webを使用している場合)
エラーの状況:
iOSでは動作するが、Android(またはreact-native-web
)でgetNativeScrollRef()
が機能しない、またはエラーになる。
原因:
react-native-web
のサポート:react-native-web
は、すべてのネイティブモジュールやメソッドを完全にサポートしているわけではありません。過去にはgetNativeScrollRef
がreact-native-web
で利用できないという問題が報告されていました(現在は修正されている可能性がありますが、古いバージョンでは起こりえます)。- プラットフォームの差異: ネイティブコンポーネントの実装はプラットフォームによって異なります。Androidでは異なるRefの構造やメソッドが必要になる場合があります。
トラブルシューティング:
react-native-web
の最新情報確認:react-native-web
を使用している場合は、そのプロジェクトのGitHubリポジトリのissueやリリースノートを確認し、getNativeScrollRef()
のサポート状況に関する情報を探してください。最新版にアップデートすることで解決する場合があります。- プラットフォーム固有のコード: 必要であれば、
Platform.OS
を使用してプラットフォームごとに異なるロジックを記述することを検討してください。
以下に、FlatList.getNativeScrollRef()
の使用例をいくつか示します。
例1: ネイティブスクロールリファレンスをログに出力する(基本的な使い方)
これは最も基本的な例で、FlatList
のネイティブスクロールリファレンスがどのように取得されるかを示します。
import React, { useRef, useEffect } from 'react';
import { FlatList, Text, View, StyleSheet } from 'react-native';
const DATA = Array.from({ length: 50 }, (_, i) => ({ id: String(i), title: `Item ${i}` }));
const BasicNativeScrollRefExample = () => {
const flatListRef = useRef(null);
useEffect(() => {
// コンポーネントがマウントされ、FlatList の Ref が利用可能になったら
if (flatListRef.current) {
// getNativeScrollRef() を使ってネイティブのスクロールリファレンスを取得
const nativeScrollRef = flatListRef.current.getNativeScrollRef();
// この nativeScrollRef は、プラットフォーム固有のネイティブビューの参照です。
// iOSでは UIScrollView、Androidでは android.widget.ScrollView など。
// 通常、直接操作することはありませんが、その存在を確認できます。
console.log('取得したネイティブスクロールRef:', nativeScrollRef);
// (開発環境のコンソールで確認してください)
// 例: iOSシミュレータでは、<RCTScrollView: 0x...> のようなオブジェクトが表示されることがあります。
// Androidエミュレータでは、<ScrollView: @...> のようなオブジェクトが表示されることがあります。
}
}, []); // コンポーネントのマウント時に一度だけ実行
const renderItem = ({ item }) => (
<View style={styles.item}>
<Text style={styles.title}>{item.title}</Text>
</View>
);
return (
<FlatList
ref={flatListRef}
data={DATA}
renderItem={renderItem}
keyExtractor={(item) => item.id}
contentContainerStyle={styles.contentContainer}
/>
);
};
const styles = StyleSheet.create({
contentContainer: {
paddingTop: 20,
},
item: {
backgroundColor: '#f9c2ff',
padding: 20,
marginVertical: 8,
marginHorizontal: 16,
borderRadius: 8,
},
title: {
fontSize: 20,
},
});
export default BasicNativeScrollRefExample;
例2: react-native-reanimated
と scrollTo
を組み合わせて使用する
これはgetNativeScrollRef()
の最も一般的なユースケースです。react-native-reanimated
のscrollTo
関数は、UIスレッドでスクロール操作を実行するためにネイティブのスクロールリファレンスを必要とします。
前提:
- アプリケーションを再ビルド(
npx react-native run-ios
/run-android
)すること。 babel.config.js
にreact-native-reanimated/plugin
が追加されていること。module.exports = { presets: ['module:@react-native/babel-preset'], plugins: [ 'react-native-reanimated/plugin', // これを追加 ], };
react-native-reanimated
がインストールされていること。npm install react-native-reanimated # または yarn add react-native-reanimated
import React, { useRef, useEffect } from 'react';
import { FlatList, Text, View, StyleSheet, Button, Dimensions } from 'react-native';
import Animated, {
useSharedValue,
useAnimatedRef,
scrollTo, // reanimated の scrollTo 関数
useAnimatedStyle,
runOnUI,
} from 'react-native-reanimated';
const { height } = Dimensions.get('window');
const ITEM_HEIGHT = 80; // アイテムの高さ + マージン
const DATA = Array.from({ length: 50 }, (_, i) => ({ id: String(i), title: `Item ${i}` }));
const AnimatedFlatList = Animated.createAnimatedComponent(FlatList);
const ReanimatedScrollExample = () => {
const animatedFlatListRef = useAnimatedRef(); // reanimated の Ref を使用
const scrollOffset = useSharedValue(0);
const scrollToIndex = (index) => {
// UIスレッドで実行
runOnUI(() => {
// getNativeScrollRef() で取得したネイティブ Ref を scrollTo に渡す
// AnimatedFlatList の Ref から直接 getNativeScrollRef() を呼び出す
const nativeScrollRef = animatedFlatListRef.current.getNativeScrollRef();
if (nativeScrollRef) {
// desiredOffset を計算
const desiredOffset = index * ITEM_HEIGHT; // 例: 各アイテムの高さで計算
// scrollTo 関数で指定のオフセットへスクロール
// scrollTo(ref, xOffset, yOffset, animated)
scrollTo(nativeScrollRef, 0, desiredOffset, true); // y軸にスクロール、アニメーションを有効にする
}
})(); // runOnUI の関数を即時実行
};
const renderItem = ({ item }) => (
<View style={styles.item}>
<Text style={styles.title}>{item.title}</Text>
</View>
);
return (
<View style={styles.container}>
<Button title="10番目のアイテムにスクロール" onPress={() => scrollToIndex(9)} />
<Button title="25番目のアイテムにスクロール" onPress={() => scrollToIndex(24)} />
<Button title="一番下へスクロール" onPress={() => scrollToIndex(DATA.length - 1)} />
<AnimatedFlatList
ref={animatedFlatListRef} // AnimatedFlatList に Ref をアタッチ
data={DATA}
renderItem={renderItem}
keyExtractor={(item) => item.id}
contentContainerStyle={styles.contentContainer}
// スクロールイベントを Reanimated でトラッキングしたい場合は onScroll を使用
// onScroll={useAnimatedScrollHandler((event) => {
// scrollOffset.value = event.contentOffset.y;
// })}
// scrollEventThrottle は onScroll の発火頻度を制御
scrollEventThrottle={16}
/>
</View>
);
};
const styles = StyleSheet.create({
container: {
flex: 1,
paddingTop: 50,
},
contentContainer: {
paddingBottom: 20, // スクロール可能領域の底に余白を追加
},
item: {
backgroundColor: '#e0f7fa',
padding: 20,
marginVertical: 8,
marginHorizontal: 16,
borderRadius: 8,
height: 64, // 例としてアイテムの高さ
justifyContent: 'center',
},
title: {
fontSize: 18,
color: '#00796b',
},
});
export default ReanimatedScrollExample;
例3: FlatList
の maintainVisibleContentPosition
との連携(高度なケース)
maintainVisibleContentPosition
は、チャットアプリケーションなどで新しいアイテムがリストの先頭や末尾に追加されたときに、現在のスクロール位置を維持するための高度なプロパティです。getNativeScrollRef()
を直接使用することは稀ですが、内部的にネイティブスクロールの動作に影響を与える可能性があるため、知っておくと良いでしょう。
このプロパティ自体がgetNativeScrollRef()
を直接使う例ではありませんが、FlatList
のスクロール動作を低レベルで制御する際の知識として関連性が高いです。
import React, { useState, useRef, useEffect, useCallback } from 'react';
import { FlatList, Text, View, StyleSheet, Button } from 'react-native';
const INITIAL_DATA_COUNT = 10;
const ADD_COUNT = 5;
const generateData = (count) => {
return Array.from({ length: count }, (_, i) => ({ id: String(i), title: `Item ${i}` }));
};
const ChatLikeListExample = () => {
const [data, setData] = useState(generateData(INITIAL_DATA_COUNT));
const flatListRef = useRef(null);
const addItemsToTop = useCallback(() => {
const newItems = Array.from(
{ length: ADD_COUNT },
(_, i) => ({ id: `new-top-${Math.random()}`, title: `New Top Item ${i}` })
);
setData((prevData) => [...newItems, ...prevData]);
}, []);
const addItemsToBottom = useCallback(() => {
const newItems = Array.from(
{ length: ADD_COUNT },
(_, i) => ({ id: `new-bottom-${Math.random()}`, title: `New Bottom Item ${i}` })
);
setData((prevData) => [...prevData, ...newItems]);
}, []);
useEffect(() => {
// 必要であれば、ここで flatListRef.current.getNativeScrollRef() を使って
// ネイティブのスクロールリファレンスにアクセスできますが、
// maintainVisibleContentPosition を使う場合は、FlatListが自動的に処理します。
// console.log(flatListRef.current?.getNativeScrollRef());
}, [data]); // データが更新された際にRefを確認したい場合
const renderItem = ({ item }) => (
<View style={styles.item}>
<Text style={styles.title}>{item.title}</Text>
</View>
);
return (
<View style={styles.container}>
<View style={styles.buttonContainer}>
<Button title="上部にアイテムを追加" onPress={addItemsToTop} />
<Button title="下部にアイテムを追加" onPress={addItemsToBottom} />
</View>
<FlatList
ref={flatListRef}
data={data}
renderItem={renderItem}
keyExtractor={(item) => item.id}
contentContainerStyle={styles.contentContainer}
// maintainVisibleContentPosition を有効にすると、
// 上部に新しいアイテムが追加されたときに、スクロール位置を維持しようとします。
// これはチャットアプリなどで非常に便利です。
maintainVisibleContentPosition={{
minIndexForVisible: 0, // 常に一番上のアイテムが見えるように試みる
autoscrollToTopThreshold: 0, // 上部に自動スクロールする閾値
}}
// invert を true にして、チャットのように下から上にアイテムを表示する
inverted
/>
</View>
);
};
const styles = StyleSheet.create({
container: {
flex: 1,
paddingTop: 50,
},
buttonContainer: {
flexDirection: 'row',
justifyContent: 'space-around',
marginBottom: 10,
},
contentContainer: {
paddingBottom: 20,
},
item: {
backgroundColor: '#ffe0b2',
padding: 20,
marginVertical: 8,
marginHorizontal: 16,
borderRadius: 8,
minHeight: 60,
justifyContent: 'center',
},
title: {
fontSize: 16,
color: '#e65100',
},
});
export default ChatLikeListExample;
しかし、多くの一般的なユースケースでは、このメソッドを使う必要はありません。FlatList
自体が豊富な高レベルAPIを提供しており、それらを使うことでスクロールの制御が可能です。また、よりパフォーマンスを重視するリストコンポーネントへの置き換えも選択肢となります。
FlatListの標準的なメソッドを使用する
ほとんどのスクロール制御のニーズは、FlatList
自体が提供する以下のメソッドで満たすことができます。これらは宣言的であり、プラットフォームの差異を抽象化してくれるため、通常はこちらの使用が推奨されます。
-
scrollToItem(params: object)
: 特定のアイテムオブジェクトまでスクロールします(scrollToIndex
よりも便利ですが、リストのデータサイズが大きい場合はscrollToIndex
+getItemLayout
の方が効率的です)。item
(object): スクロール先のアイテムオブジェクト(必須)。animated
(boolean): スクロールをアニメーションさせるかどうか。viewPosition
(number): スクロール先のアイテムをビューのどこに配置するか。 例:
// const targetItem = DATA[DATA.length - 1]; // 例: 最後のアイテム // <Button title="指定アイテムへスクロール" onPress={() => flatListRef.current.scrollToItem({ item: targetItem, animated: true })} />
-
scrollToEnd(params?: { animated?: boolean })
: リストの末尾までスクロールします。animated
(boolean): スクロールをアニメーションさせるかどうか(デフォルトはtrue
)。 例:
// <Button title="一番下へスクロール" onPress={() => flatListRef.current.scrollToEnd({ animated: true })} />
-
scrollToOffset(params: object)
: 指定したオフセット(ピクセル単位)までスクロールします。offset
(number): スクロール先のピクセルオフセット(必須)。horizontal
がtrue
の場合はX軸、それ以外はY軸。animated
(boolean): スクロールをアニメーションさせるかどうか(デフォルトはtrue
)。 例:
// 上記の例の Button 部分を以下のように変更 // <Button title="上から200pxにスクロール" onPress={() => flatListRef.current.scrollToOffset({ offset: 200, animated: true })} />
-
scrollToIndex(params: object)
: 特定のインデックスのアイテムまでスクロールします。index
(number): スクロール先のアイテムのインデックス(必須)。animated
(boolean): スクロールをアニメーションさせるかどうか(デフォルトはtrue
)。viewOffset
(number): 最終的なターゲット位置からの固定オフセット(ピクセル)。viewPosition
(number): スクロール先のアイテムをビューのどこに配置するか(0: トップ、0.5: 中央、1: ボトム)。 例:
import React, { useRef } from 'react'; import { FlatList, Button, View, Text, StyleSheet } from 'react-native'; const DATA = Array.from({ length: 100 }, (_, i) => ({ id: String(i), title: `Item ${i}` })); function FlatListStandardMethods() { const flatListRef = useRef(null); const scrollToItemByIndex = (index) => { flatListRef.current.scrollToIndex({ index: index, animated: true, viewPosition: 0.5, // 中央に表示 }); }; return ( <View style={styles.container}> <Button title="50番目のアイテムにスクロール" onPress={() => scrollToItemByIndex(49)} /> <FlatList ref={flatListRef} data={DATA} renderItem={({ item }) => ( <View style={styles.item}> <Text>{item.title}</Text> </View> )} keyExtractor={(item) => item.id} getItemLayout={(data, index) => ( { length: 50, offset: 50 * index, index } // パフォーマンス向上のため設定を推奨 )} /> </View> ); } const styles = StyleSheet.create({ container: { flex: 1, paddingTop: 50 }, item: { padding: 10, borderBottomWidth: 1, borderBottomColor: '#ccc', height: 50 }, }); export default FlatListStandardMethods;
ScrollViewの直接操作(FlatListの代わりに)
もしリストが非常に短く、仮想化の恩恵をあまり受けない場合(例: 画面に収まる程度のアイテム数)、FlatList
の代わりにScrollView
を使用することもできます。ScrollView
はFlatList
よりもシンプルで、そのRefを介して直接scrollTo
メソッドを呼び出すことができます。
import React, { useRef } from 'react';
import { ScrollView, Button, View, Text, StyleSheet } from 'react-native';
function ScrollViewDirectControl() {
const scrollViewRef = useRef(null);
const scrollToTop = () => {
scrollViewRef.current.scrollTo({ x: 0, y: 0, animated: true });
};
const scrollToBottom = () => {
scrollViewRef.current.scrollToEnd({ animated: true });
};
return (
<View style={styles.container}>
<Button title="一番上へスクロール" onPress={scrollToTop} />
<Button title="一番下へスクロール" onPress={scrollToBottom} />
<ScrollView
ref={scrollViewRef}
style={styles.scrollView}
contentContainerStyle={styles.scrollViewContent}
>
{Array.from({ length: 50 }, (_, i) => (
<View key={i} style={styles.item}>
<Text>ScrollView Item {i}</Text>
</View>
))}
</ScrollView>
</View>
);
}
const styles = StyleSheet.create({
container: { flex: 1, paddingTop: 50 },
scrollView: { flex: 1 },
scrollViewContent: { paddingBottom: 20 },
item: { padding: 15, borderBottomWidth: 1, borderBottomColor: '#eee' },
});
export default ScrollViewDirectControl;
注意: ScrollView
はすべてのコンテンツを一度にレンダリングするため、リストが長くなるとパフォーマンスの問題が発生する可能性があります。
FlashListの使用 (Shopify製)
もしFlatList
のパフォーマンスに不満があり、getNativeScrollRef()
のような低レベルな最適化を検討しているなら、Shopifyが開発したFlashList
を検討する価値があります。FlashList
はFlatList
とほぼ同じAPIを持ちながら、より効率的なビューのリサイクル機構によって、非常に大規模なリストでも優れたパフォーマンスを発揮します。
FlashList
もFlatList
と同様にscrollToIndex
やscrollToOffset
などのメソッドを提供しており、通常はgetNativeScrollRef()
のような低レベルなAPIに頼る必要はありません。
前提:
@shopify/flash-list
をインストールnpm install @shopify/flash-list # または yarn add @shopify/flash-list
例:
(APIはFlatList
とほぼ同じです)
import React, { useRef } from 'react';
import { Button, View, Text, StyleSheet } from 'react-native';
import { FlashList } from '@shopify/flash-list';
const DATA = Array.from({ length: 5000 }, (_, i) => ({ id: String(i), title: `FlashList Item ${i}` }));
function FlashListExample() {
const flashListRef = useRef(null);
const scrollToIndex = (index) => {
flashListRef.current.scrollToIndex({
index: index,
animated: true,
viewPosition: 0.5,
});
};
return (
<View style={styles.container}>
<Button title="2500番目のアイテムにスクロール (FlashList)" onPress={() => scrollToIndex(2499)} />
<FlashList
ref={flashListRef}
data={DATA}
renderItem={({ item }) => (
<View style={styles.item}>
<Text>{item.title}</Text>
</View>
)}
estimatedItemSize={50} // 必須または強く推奨
keyExtractor={(item) => item.id}
/>
</View>
);
}
const styles = StyleSheet.create({
container: { flex: 1, paddingTop: 50 },
item: { padding: 10, borderBottomWidth: 1, borderBottomColor: '#ccc', height: 50 },
});
export default FlashListExample;
ポイント: FlashList
では、estimatedItemSize
プロパティの設定がパフォーマンスのために非常に重要です。
FlatList.getNativeScrollRef()
は特定のニッチなユースケース(主にreact-native-reanimated
との連携)で強力ですが、ほとんどのスクロール制御の要件は、FlatList
の標準メソッド(scrollToIndex
, scrollToOffset
, scrollToEnd
)で十分に満たせます。