React Native @gorhom/bottom-sheet键盘关闭时自动展开问题求助
React Native Bottom Sheet 自动展开问题
依赖版本
"@gorhom/bottom-sheet": "^4", "@hookform/resolvers": "^3.0.0", "@react-navigation/drawer": "^6.6.2", "@react-navigation/native": "^6.1.6", "@react-navigation/stack": "^6.3.16", "react-hook-form": "^7.43.8", "react-native": "0.71.4", "react-native-paper": "^5.5.2",
问题描述
TextInput 不在 BottomSheet 组件内部,但当 TextInput 获取焦点后,关闭键盘或让输入框失焦时,bottom sheet 会自动展开,而非通过 ref 对象触发。
应用最简配置
App.ts
const App = () => { return ( <PaperProvider theme={theme}> <NavigationContainer onReady={RNBootSplash.hide}> <PortalProvider> <AppNavigator /> </PortalProvider> </NavigationContainer> </PaperProvider> ); }
AppNavigator.ts
const Stack = createStackNavigator(); const AppNavigator = () => { return ( <> <Stack.Navigator detachInactiveScreens={true} screenOptions={{ animationEnabled: true, headerShown: false, cardStyleInterpolator: CardStyleInterpolators.forScaleFromCenterAndroid }} initialRouteName={ScreenRouteEnum.HOME} > <Stack.Screen name={ScreenRouteEnum.HOME} component={MainScreen} /> <Stack.Screen name={ScreenRouteEnum.ADD_POLE} component={AddPole} /> </Stack.Navigator> <PortalHost name="addPolePortal" /> </> ); };
AddPole.ts
const voltage = [ { pole_voltage_id: 1, pole_voltage_name: '69KV' } ] const AddPole = () => { const snapPointsVoltage = useMemo(() => ['25%'], []); const bottomSheetRef = useRef<BottomSheet>(null); const renderBackdrop = useCallback( (props: any) => ( <BottomSheetBackdrop {...props} disappearsOnIndex={-1} appearsOnIndex={0} /> ), [] ); const handleSheetChanges = useCallback((index: number) => { console.log('handleSheetChanges', index); }, []); const onOpenSheet = () => { bottomSheetRef?.curret?.collapse(); } return ( <> <TextInput placeholder="Write something" /> <Button onClick={onOpenSheet}> Open Sheet </Button> <Portal hostName="addPolePortal"> <BottomSheet ref={bottomSheetRef} index={-1} snapPoints={snapPointsVoltage} enablePanDownToClose onChange={handleSheetChanges} backdropComponent={renderBackdrop} handleIndicatorStyle={{ backgroundColor: '#a1a1a1' }} > <BottomSheetView style={styles.bottomSheetContainer}> {voltage.map(a => ( <TouchableRipple key={a.pole_voltage_id} style={styles.menuItemInner} rippleColor="rgba(0, 0, 0, .1)" onPress={onPress} > <Text style={styles.menuText}>{a.pole_voltage_name}</Text> </TouchableRipple> ))} </BottomSheetView> </BottomSheet> </Portal> </> ); } const styles = StyleSheet.create({ bottomSheetContainer: { paddingVertical: 15, flex: 1 }, }) export default AddPole;
已尝试的解决方法
设置 keyboardBlurBehavior="none",但问题未解决。
解决方案
1. 禁用BottomSheet的键盘交互
@gorhom/bottom-sheet 默认会监听键盘事件调整自身状态,即使输入框不在Sheet内也可能触发异常。可以通过 keyboardBehavior 属性完全禁用键盘相关自动调整:
<BottomSheet ref={bottomSheetRef} index={-1} snapPoints={snapPointsVoltage} enablePanDownToClose onChange={handleSheetChanges} backdropComponent={renderBackdrop} handleIndicatorStyle={{ backgroundColor: '#a1a1a1' }} keyboardBehavior="none" // 添加此属性 />
2. 手动控制Sheet的启用状态
在TextInput焦点变化时,手动禁用/启用Sheet的交互能力,避免键盘事件误触:
const AddPole = () => { // ... 其他代码 const [inputFocused, setInputFocused] = useState(false); return ( <> <TextInput placeholder="Write something" onFocus={() => setInputFocused(true)} onBlur={() => setInputFocused(false)} /> <Portal hostName="addPolePortal"> <BottomSheet // ... 其他属性 enabled={!inputFocused} // 输入框聚焦时禁用Sheet交互 > {/* ... Sheet内容 */} </BottomSheet> </Portal> </> ); }
3. 修正代码拼写错误
注意到 onOpenSheet 函数中 bottomSheetRef?.curret?.collapse() 存在拼写错误,curret 应为 current,且如果是要打开Sheet,应该用 expand() 而非 collapse():
const onOpenSheet = () => { bottomSheetRef?.current?.expand(); }
4. 调整Portal层级
尝试将BottomSheet移出Portal,直接放在AddPole组件的根容器内,排查是否是Portal层级导致的事件冒泡问题:
return ( <View style={{ flex: 1 }}> <TextInput placeholder="Write something" /> <Button onClick={onOpenSheet}> Open Sheet </Button> <BottomSheet ref={bottomSheetRef} index={-1} snapPoints={snapPointsVoltage} enablePanDownToClose onChange={handleSheetChanges} backdropComponent={renderBackdrop} handleIndicatorStyle={{ backgroundColor: '#a1a1a1' }} > {/* ... Sheet内容 */} </BottomSheet> </View> );
内容的提问来源于stack exchange,提问作者Julius Guevarra
相关产品推荐
相关产品推荐

