Expo应用加载最后一页时出现'Bubbling event type of null'错误求助
你好,我仔细看了你的问题描述和提供的代码,这个「Bubbling event type of null」错误一般和React Native组件的事件处理逻辑、渲染异常或者状态管理问题有关,结合你的代码,我整理了几个核心问题点和对应的修复方案,你可以逐一尝试:
1. 无限循环的useEffect引发的异常
你的EditScreen组件里的useEffect没有设置依赖数组,这会导致它在组件每次渲染时都重复执行,而且里面的setTimeout会不断创建新的定时器,最终引发内存泄漏和异常。另外,定时器也没有清理,组件卸载后还会继续执行,这也会导致奇怪的错误。
修复方式:
- 给
useEffect添加正确的依赖数组,让它只在依赖项变化时执行 - 添加清理函数,在组件卸载或依赖变化时清除定时器
useEffect(() => { let timer; if (!isPaused) { timer = setTimeout(() => { setCurrentTime(prev => prev + 1000); console.log('current time is', currentTime); }, 1000); } // 清理函数:清除定时器 return () => clearTimeout(timer); }, [currentTime, isPaused, lenghtOfAllPreviousVideous, currentVideoNumber]); // 添加依赖数组
2. 函数组件中错误使用this引用
你的TimeLine组件是函数组件,但里面用了this.listRef、this.init这类class组件的写法,函数组件没有this,这会导致undefined错误,进而触发事件冒泡相关的异常。
修复方式:改用useRef钩子来存储引用值
const TimeLine = () => { const outerListRef = useRef(null); const initRef = useRef(null); // 替代this.init // ... 其他代码 return ( <FlatList // ... 外层FlatList属性 renderItem={({item}) => ( <View> {/* ... */} <FlatList ref={outerListRef} // 替代this.listRef // ... 内层FlatList属性 onScrollBeginDrag={(event) => { initRef.current = event.nativeEvent.contentOffset.x; // 用ref.current存储 }} onScrollEndDrag={(event) => { if (initRef.current < event.nativeEvent.contentOffset.x) { // ... 逻辑 } else { // ... 逻辑 } }} /> </View> )} /> ); };
3. 嵌套FlatList的data来源错误
TimeLine里的内层FlatList直接用makeData(item)作为data,但makeData是async函数,返回的是Promise而不是数组,FlatList无法正确渲染,这会导致组件渲染异常,进而引发事件错误。
修复方式:用useState存储缩略图数据,通过useEffect异步获取
const TimeLineItem = ({item}) => { const [thumbnails, setThumbnails] = useState([]); useEffect(() => { const fetchThumbnails = async () => { const list = []; let time = 0; const videoDuration = await getVideoDuration(item.uri); // 替换硬编码的1000,用实际视频时长 while (time < videoDuration * 1000) { try { const accessibleUri = await convertPhUriToAccessible(item); const thumbnail = await VideoThumbnails.getThumbnailAsync( accessibleUri, { time: time } ); list.push(thumbnail); time += timeLenghtOfOneFrame; } catch (err) { console.log('缩略图生成错误:', err); } } setThumbnails(list); }; fetchThumbnails(); }, [item]); return ( <FlatList data={thumbnails} // ... 其他属性 /> ); }; // 然后在TimeLine的外层FlatList里渲染TimeLineItem const TimeLine = () => { return ( <FlatList data={selectedItems} renderItem={({item}) => <TimeLineItem item={item} />} // ... 其他属性 /> ); };
4. 子组件未接收必要的状态props
你的MenuBar组件里直接使用了selectedItems和currentVideoNumber,但这两个状态是EditScreen组件的局部状态,MenuBar没有通过props接收,会导致undefined错误,这也是引发异常的潜在原因。
修复方式:把状态作为props传给MenuBar
// 在EditScreen里渲染MenuBar时传递props return ( <View style={styles.container}> {/* ... 其他组件 */} <MenuBar selectedItems={selectedItems} currentVideoNumber={currentVideoNumber} setCurrentVideoNumber={setCurrentVideoNumber} setSelectedItems={/* 如果需要修改数组,传递对应的setter */} /> </View> ); // 然后在MenuBar组件里接收props const MenuBar=({selectedItems, currentVideoNumber, setCurrentVideoNumber, setSelectedItems})=>{ const buttonsData=["Split","Delete","Speed"] return( <FlatList data={buttonsData} renderItem={({item}) => ( <Button onPress={()=>{ switch (item) { case "Split": const currentVideo=selectedItems[currentVideoNumber]; // 不直接修改原数组,创建新数组更新状态 const newItems = [...selectedItems]; newItems.splice(currentVideoNumber, 1); newItems.splice(currentVideoNumber, 0, currentVideo); setSelectedItems(newItems); break; case "Delete": const updatedItems = [...selectedItems]; updatedItems.splice(currentVideoNumber, 1); setSelectedItems(updatedItems); setCurrentVideoNumber(prev => Math.max(0, prev - 1)); break; case "Speed": default: Alert.alert(item) } }} title={item} /> )} horizontal /> ) }
最后建议的修复步骤:
- 先修复
useEffect的依赖和定时器清理问题,这是最容易引发无限循环和异常的点 - 修正函数组件中
this的使用,全部替换为useRef - 调整嵌套FlatList的缩略图数据获取逻辑,确保
data是正确的数组 - 给子组件传递必要的props,避免访问未定义的状态
- 之后执行
npx expo start --clear重新启动项目测试
内容来源于stack exchange

