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的手势逻辑冲突。
- 给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
相关产品推荐
相关产品推荐

