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

TypeScript编写的BottomSheet在Release模式崩溃,仅传ScrollView时触发

问题描述

我用TypeScript编写了一个BottomSheet组件,在类组件中导入使用时,Debug模式下运行正常,但切换到Release模式就直接崩溃。查看Logcat也找不到可读的错误信息,给TS组件外层加了try-catch也无法阻止崩溃。

我的TypeScript组件代码:

export default function App(data: any) {
   const ref = useRef<BottomSheetRefProps>(null);

   const onPressCloseBottomSheet = useCallback(() => {
      const isActive = ref?.current?.isActive();
      if (isActive) {
         ref?.current?.scrollTo(0);
         data.data.onCloseBottomSheetParam();
      } else {
         ref?.current?.scrollTo(-(styles.windowHeight / 1.8));
      }
   }, []);

   var custom_view = data.data.custom_view;

   try {
      return (
         <GestureHandlerRootView style={styles.bottomSheetOuterWrapper}>
            <BlurView
               style={styles.blurViewStyle}
               blurRadius={1}
               blurType={'dark'}
            />
            <View style={styles.innerContainerBottomSheet}>
               <BottomSheet ref={ref}>
                  {data.data.onCloseBottomSheetParam}
                  {custom_view}                 
               </BottomSheet>
            </View>
         </GestureHandlerRootView>
      );
   } catch (e) {
      alert('BottomSheet called failed!');
      return null;
   };
}

类组件中使用该BottomSheet的代码片段:

try {
 const customview = (<ScrollView
    contentContainerStyle={styles.userEmojisScrollableView}>
    {Object.keys(all_active_users).map(e =>
       all_active_users[e].act &&
       <View style={styles.userEmojisScrollableInnerView}>
          <View style={styles.usrEmojisNameImgWrapper}>
             <FastImage
                source={all_active_users[e].profile_pic ? {
                   uri: all_active_users[e].profile_pic,
                   priority: FastImage.priority.high,
                   cache: FastImage.cacheControl.immutable,
                } : require('../assets/user.png')}
                style={styles.usrEmojiPic}
                resizeMode={FastImage.resizeMode.cover}
             />
             <Text style={styles.usrEmojiUsernameTxt}>
                {all_active_users[e].name}
             </Text>
          </View>
       </View>
    )}
 </ScrollView>);

  return (<BottomSheet data={{ custom_view: customview, onCloseBottomSheetParam: (() => this.onCloseBottomSheet()) }} />);
  } catch (e) {
     logErrors('openModalActiveUsers()', e);
     alert('openModalActiveUsers() failed!');
     return;
  };

更新:我发现只有向TypeScript组件传入ScrollView时才会崩溃,换成其他React子组件就没有问题。现在想知道为什么ScrollView会导致Release模式下应用崩溃?


可能的原因及解决方案

1. 代码混淆/压缩导致的方法丢失

Release打包时默认开启代码混淆和压缩,ScrollView或其内部FastImage的关键方法、属性可能被误混淆重命名,导致运行时找不到对应逻辑触发崩溃。

  • 解决:在metro.config.js或项目混淆配置文件中,给ScrollView、FastImage相关类添加白名单,避免关键代码被篡改。

2. 列表项缺少唯一key属性

你在ScrollView的map循环中没有给子元素添加key属性。Debug模式下React会容忍这种情况,但Release模式下的严格优化逻辑会触发渲染异常。

  • 解决:给map返回的View加上唯一key,比如使用循环的e(确保e是唯一ID):
{Object.keys(all_active_users).map(e =>
   all_active_users[e].act &&
   <View key={e} style={styles.userEmojisScrollableInnerView}>
      // ... 其余代码
   </View>
)}

3. BottomSheet与ScrollView的手势冲突

BottomSheet自带拖拽/滚动手势,和内部ScrollView的手势在Release模式下的处理逻辑存在冲突,导致手势处理时崩溃。

  • 解决:
    • 给ScrollView添加nestedScrollEnabled={true}属性,开启嵌套滚动支持;
    • 配置BottomSheet的手势拦截规则,避免和内部ScrollView的手势逻辑冲突。

4. 类型不匹配引发的隐式错误

你的TS组件中data参数类型设为any,传入custom_view时可能存在隐式类型转换,Debug模式下类型检查宽松不会报错,但Release模式下的类型优化会触发崩溃。

  • 解决:给data定义明确的类型约束:
interface BottomSheetProps {
  data: {
    custom_view: React.ReactNode;
    onCloseBottomSheetParam: () => void;
  };
}

export default function App(data: BottomSheetProps) {
  // ... 其余代码
}

5. 布局计算异常导致的越界访问

Release模式下的布局优化可能导致ScrollView的高度计算异常,结合BottomSheet的动态高度逻辑,触发空指针或数组越界访问。

  • 解决:
    • 给ScrollView设置明确的高度限制;
    • 检查BottomSheet的scrollTo方法参数是否合法,比如确认styles.windowHeight在Release模式下是否能正确获取设备窗口高度。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.12 08:15:46