React Native Paper Snackbar组件超时触发'Uncaught Error'问题求助
React Native Paper Snackbar 超时触发"Cannot read property 'apply' of undefined"错误解决
问题概述
使用 React Native Paper 5.10.6 的 Snackbar 组件时,当组件显示达到默认时长自动隐藏时,会触发未捕获错误:Uncaught Error - Cannot read property 'apply' of undefined,调用栈指向 node_modules\react-native\Libraries\Core\Timers\JSTimers.js 和 node_modules\react-native\BatchedBridge\MessageQueue.js。当前使用 React Native 版本为 0.72.6,相关代码如下:
// Components import LostObjects from "../components/LostObjects"; import FoundObjects from "../components/FoundObjects"; import TabBar from "../components/TabBar"; import Home from "../pages/Home"; import PrimaryFAB from "../components/PrimaryFAB"; import { Portal, Snackbar, Text } from "react-native-paper"; // Data import RegisteredObjectsData from "../mockup/RegisteredObjectsData"; const { lostObjects, foundObjects } = RegisteredObjectsData; // Styles import { global } from "../styles/global"; export default function RegisteredObjectsRoutes({ navigation, route }) { const page = foundObjects.length || lostObjects.length ? ( <TabBar screens={[ { component: LostObjects, title: "Objetos Perdidos" }, { component: FoundObjects, title: "Objetos Achados" }, ]} hasBadge={[ RegisteredObjectsData.lostObjects.length, RegisteredObjectsData.foundObjects.length, ]} /> ) : ( <Home /> ); return ( <> {page} <PrimaryFAB style={global.fabButton} icon="plus" label="Novo Registro" onPress={() => navigation.navigate("ObjectRegister")} /> <Portal> <Snackbar visible={route?.params ? true : false}> { RegisteredObjectsData[ route?.params?.foundObject ? "foundObjects" : "lostObjects" ][route?.params?.objectId - 1]?.object + " apagado com sucesso" } </Snackbar> </Portal> </> ); }
原因分析
- 状态管理不当:直接将
Snackbar的visible属性绑定到路由参数route.params,没有通过组件内部状态控制,导致组件在路由参数变化或自动隐藏时,内部定时器回调逻辑出现异常。 - 内容渲染不稳定:Snackbar 的消息内容直接依赖路由参数和数组索引获取,若参数缺失或索引越界,会导致
undefined与字符串拼接,间接影响组件内部状态稳定性。 - 版本兼容性问题:React Native Paper 5.10.6 与 React Native 0.72.6 的定时器逻辑存在兼容性冲突,自动隐藏时清理定时器的回调被意外置为
undefined,触发apply调用错误。
解决方案
1. 改用组件内部状态控制Snackbar
通过 useState 维护 Snackbar 的可见性和消息内容,配合 useEffect 监听路由参数变化,实现更可控的显示逻辑。
2. 显式处理消息内容与隐藏回调
确保消息内容渲染稳定,添加 onDismiss 回调正确更新状态,避免内部逻辑异常。
修改后的代码示例
// Components import { useState, useEffect } from 'react'; import LostObjects from "../components/LostObjects"; import FoundObjects from "../components/FoundObjects"; import TabBar from "../components/TabBar"; import Home from "../pages/Home"; import PrimaryFAB from "../components/PrimaryFAB"; import { Portal, Snackbar, Text } from "react-native-paper"; // Data import RegisteredObjectsData from "../mockup/RegisteredObjectsData"; const { lostObjects, foundObjects } = RegisteredObjectsData; // Styles import { global } from "../styles/global"; export default function RegisteredObjectsRoutes({ navigation, route }) { const [snackbarVisible, setSnackbarVisible] = useState(false); const [snackbarMessage, setSnackbarMessage] = useState(''); // 监听路由参数变化,触发Snackbar显示 useEffect(() => { if (route?.params) { const objectType = route.params.foundObject ? 'foundObjects' : 'lostObjects'; const objectItem = RegisteredObjectsData[objectType][route.params.objectId - 1]; // 确保对象存在再设置消息 if (objectItem?.object) { setSnackbarMessage(`${objectItem.object} apagado com sucesso`); setSnackbarVisible(true); } } }, [route.params]); const page = foundObjects.length || lostObjects.length ? ( <TabBar screens={[ { component: LostObjects, title: "Objetos Perdidos" }, { component: FoundObjects, title: "Objetos Achados" }, ]} hasBadge={[ RegisteredObjectsData.lostObjects.length, RegisteredObjectsData.foundObjects.length, ]} /> ) : ( <Home /> ); return ( <> {page} <PrimaryFAB style={global.fabButton} icon="plus" label="Novo Registro" onPress={() => navigation.navigate("ObjectRegister")} /> <Portal> <Snackbar visible={snackbarVisible} onDismiss={() => setSnackbarVisible(false)} duration={3000} // 显式设置时长,避免默认逻辑冲突 > {snackbarMessage} </Snackbar> </Portal> </> ); }
额外建议
如果问题仍未解决,可尝试升级 React Native Paper 到 5.x 系列的最新兼容版本,或检查项目中是否存在全局定时器清理逻辑,避免干扰 Snackbar 内部的定时器管理。
内容的提问来源于stack exchange,提问作者André Coelho
相关产品推荐
相关产品推荐

