You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React Native中如何将FlatList数据传递给BottomSheet?

实现FlatList点击按钮打开共享BottomSheet并传递对应数据

核心思路

不需要为每个列表项创建独立的BottomSheet,只需维护一个共享的BottomSheet实例,通过状态管理当前选中的列表项数据,点击按钮时更新状态并触发BottomSheet打开即可,这样能大幅提升性能。

修改后的完整代码

import { BottomSheetModal, BottomSheetModalProvider, BottomSheetScrollView } from '@gorhom/bottom-sheet';
import { useRef, useState, useCallback, useMemo } from "react";
import { View, FlatList, Text, TouchableOpacity } from 'react-native';

// 模拟自定义AppButton组件,实际替换为你的按钮组件即可
const AppButton = ({ title, style, onPress }) => (
  <TouchableOpacity style={[{ padding: 10, backgroundColor: '#eee', borderRadius: 8 }, style]} onPress={onPress}>
    <Text>{title}</Text>
  </TouchableOpacity>
);

const DATA = [
    {
        id: 'bd7acbea-c1b1-46c2-aed5-3ad53abb28ba',
        title: 'John Doe',
    },
    {
        id: '3ac68afc-c605-48d3-a4f8-fbd91aa97f63',
        title: 'John Smith',
    },
    {
        id: '58694a0f-3da1-471f-bd96-145571e29d72',
        title: 'John Lennon',
    },
];

const Item = ({ title, onPress }) => (
    <AppButton title={title} style={{ marginVertical: 10 }} onPress={onPress} />
);

const App = () => {
    // 获取BottomSheetModal实例,用于调用打开/关闭方法
    const bottomSheetModalRef = useRef(null);
    // 存储当前选中的列表项数据
    const [selectedItem, setSelectedItem] = useState(null);

    // 缓存BottomSheet停靠点,避免每次渲染重新创建数组
    const snapPoints = useMemo(() => ['25%', '50%'], []);

    // 缓存打开BottomSheet的函数,减少不必要的重渲染
    const handlePresentModalPress = useCallback(() => {
        bottomSheetModalRef.current?.present();
    }, []);

    // 处理列表项点击:先设置选中数据,再打开BottomSheet
    const handleItemPress = useCallback((item) => {
        setSelectedItem(item);
        handlePresentModalPress();
    }, [handlePresentModalPress]);

    const handleSheetChanges = useCallback((index) => {
        console.log('BottomSheet状态变化:', index);
    }, []);

    return (
        <BottomSheetModalProvider>
            <View style={{ flex: 1, padding: 20 }}>
                <FlatList
                    data={DATA}
                    keyExtractor={item => item.id}
                    renderItem={({ item }) => <Item title={item.title} onPress={() => handleItemPress(item)} />}
                />
            </View>

            <BottomSheetModal
                ref={bottomSheetModalRef}
                index={0}
                snapPoints={snapPoints}
                enablePanDownToClose
                onChange={handleSheetChanges}
            >
                <BottomSheetScrollView style={{ padding: 20 }}>
                    {/* 展示选中的列表项数据 */}
                    {selectedItem && (
                        <Text>当前选中:{selectedItem.title}</Text>
                    )}
                </BottomSheetScrollView>
            </BottomSheetModal>
        </BottomSheetModalProvider>
    )
}

export default App;

关键部分解释

  1. BottomSheetModalProvider层级修正
    必须将所有使用BottomSheet的组件(包括FlatList)包裹在BottomSheetModalProvider内部,否则BottomSheet无法正常工作,原代码中Provider与View同级的写法是错误的。

  2. useRef的作用
    bottomSheetModalRef用来存储BottomSheetModal的实例,通过current属性可以调用组件内置的present()、dismiss()等方法。ref的特性是跨组件渲染周期保存引用,不会因组件重新渲染丢失实例,这是复用同一个BottomSheet的核心。

  3. useCallback的作用
    用useCallback包裹handlePresentModalPress和handleItemPress,是为了缓存函数引用,避免组件每次重新渲染时创建新的函数实例。这样能减少FlatList子组件的不必要重渲染,提升性能。

  4. 状态管理选中数据
    通过useState创建selectedItem状态,点击列表项时先更新该状态,再打开BottomSheet,确保BottomSheet能获取并展示当前选中项的数据。

  5. 复用BottomSheet的优势
    仅维护一个BottomSheet实例,相比为每个列表项创建独立的BottomSheet,能大幅减少内存占用和组件初始化开销,数据量越大,性能提升越明显。

内容的提问来源于stack exchange,提问作者serking

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.02 04:55:23