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

@gorhom Bottom Sheet转发Ref为undefined问题求助

问题分析与解决方案

你的代码存在三个核心问题,导致点击触发时ref.current为undefined,下面逐一说明并给出修正后的代码:


1. 未渲染BottomSheet组件

在LocationBar组件中,<LocationBottomSheet ref={userBottomSheetRef} snapPoints={["30%"]}/>这行代码没有被包含在return的JSX结构里,组件从未被挂载,因此ref无法获取到实例。

2. 函数组件Ref转发错误

函数组件默认不接收ref作为props,必须使用React.forwardRef包装组件,才能将父组件传递的ref转发到底层的BottomSheetModal上。原代码直接接收ref作为props是无效的。

3. BottomSheetModalProvider位置错误

BottomSheetModalProvider是弹窗的上下文提供者,应该放在应用根组件(如App.tsx)中,确保所有子组件共享同一个上下文。放在单个BottomSheet组件内部会导致上下文隔离,弹窗方法无法正常调用。


修正后的代码

1. 修正BottomSheetModalComponent(使用forwardRef)

import React, { forwardRef, useCallback } from 'react';
import { View, Text } from 'react-native';
import { BottomSheetModal } from '@gorhom/bottom-sheet';

// 使用forwardRef转发ref到底层弹窗组件
const BottomSheetModalComponent = forwardRef(({ snapPoints = ['25%', '50%'] }, ref) => {
  const handleSheetChanges = useCallback((index: number) => {
    console.log('handleSheetChanges', index);
  }, []);

  return (
    <View>
      <BottomSheetModal
        ref={ref}
        snapPoints={snapPoints}
        onChange={handleSheetChanges}
      >
        <View>
          <Text>Awesome 🎉</Text>
        </View>
      </BottomSheetModal>
    </View>
  );
});

export default BottomSheetModalComponent;

2. 修正LocationBar组件(渲染BottomSheet并传递ref)

import React, { useRef } from 'react';
import { View, TouchableOpacity, Text, StyleSheet } from 'react-native';
import Octicons from '@expo/vector-icons/Octicons';
import Ionicons from '@expo/vector-icons/Ionicons';
import BottomSheetModalComponent from './BottomSheetModalComponent';

export default function LocationBar() {
  const userBottomSheetRef = useRef(null);
  const userLocation = "当前位置";

  return (
    <>
      <View style={{ flexDirection: "row" }}>
        <View style={styles.locationBar}>
          <Octicons style={styles.locationIcon} name="location" size={18} />
          <TouchableOpacity onPress={() => {
            userBottomSheetRef.current?.present();
          }}>
            <Text style={{fontSize: 17, fontWeight: '600'}}>{userLocation}</Text>
          </TouchableOpacity>
          <Ionicons style={styles.chevronIcon} name="chevron-down" size={12} />
        </View>
      </View>
      {/* 将BottomSheet组件放到return的JSX中,确保被渲染 */}
      <BottomSheetModalComponent 
        ref={userBottomSheetRef} 
        snapPoints={["30%"]} 
      />
    </>
  );
}

const styles = StyleSheet.create({
  locationBar: {
    flexDirection: 'row',
    alignItems: 'center',
    gap: 8,
    padding: 12,
  },
  locationIcon: {
    color: '#666',
  },
  chevronIcon: {
    color: '#666',
    marginLeft: 4,
  },
});

3. 根组件添加BottomSheetModalProvider

import { BottomSheetModalProvider } from '@gorhom/bottom-sheet';
import LocationBar from './LocationBar';

export default function App() {
  return (
    <BottomSheetModalProvider>
      <LocationBar />
      {/* 其他应用组件 */}
    </BottomSheetModalProvider>
  );
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.10 01:55:15