@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
相关产品推荐
相关产品推荐

