使用SQLite实现TodoList数据持久化时遇React Native报错求助
解决Expo Go中TodoList SQLite持久化的报错问题
问题根源分析
Invariant Violation: "main" has not been registered:代码存在语法/逻辑错误,导致模块加载失败,AppRegistry无法完成注册。TypeError: Cannot convert null value to object:存在未定义变量、SQL字段不匹配以及Expo不兼容的SQLite库使用问题。
具体修复步骤
1. 替换Expo兼容的SQLite库
Expo官方不支持react-native-sqlite-storage,必须使用expo-sqlite:
# 卸载旧库 npm uninstall react-native-sqlite-storage # 安装expo官方SQLite库 npx expo install expo-sqlite
修改代码中的导入和数据库初始化逻辑:
// 替换原SQLite导入语句 import * as SQLite from 'expo-sqlite'; // 初始化数据库(expo-sqlite的初始化更简洁) const db = SQLite.openDatabase('TodoList.db');
2. 修复变量与SQL字段不匹配问题
- 状态变量定义为
text,但handleAddTodo中误用了未定义的todoText,统一替换为text; - 建表时字段为
value,但插入、查询用的是text,统一字段名保证一致性:
// 修正建表语句,统一字段名为text const createTable = () => { db.transaction((tx) => { tx.executeSql(`CREATE TABLE IF NOT EXISTS todos (id INTEGER PRIMARY KEY AUTOINCREMENT, text TEXT NOT NULL);`); }); }; // 修正添加待办的函数 const handleAddTodo = () => { if (text.length > 0) { db.transaction((tx) => { tx.executeSql( "INSERT INTO todos (text) VALUES (?)", [text], // 替换todoText为定义好的text状态 () => { console.log("Todo added successfully"); fetchTodos(); setText(""); // 替换setTodoText为setText }, (_, error) => { console.log("Error adding todo: ", error); } ); }); } };
3. 修复主题切换逻辑错误
Appearance.addChangeListener的回调错误地将主题值转为布尔值,导致后续主题判断失效:
useEffect(() => { createTable(); fetchTodos(); const subscription = Appearance.addChangeListener(({ colorScheme }) => { setThemeMode(colorScheme); // 直接赋值"light"或"dark",而非布尔值 }); return () => { subscription.remove(); }; }, []);
同时修正主题样式的判断逻辑(原代码条件写反):
const containerStyle = themeMode === "dark" ? styles.containerDark : styles.containerLight; const iconColor = themeMode === "dark" ? "white" : "#292929"; const textColor = themeMode === "dark" ? "white" : "#292929";
4. 重置Metro服务器清除缓存
停止当前运行的Metro服务器,在项目根目录执行命令重置缓存:
npm start -- --reset-cache
之后重新扫码在Expo Go中加载项目。
内容的提问来源于stack exchange,提问作者Matteo_Konsept
相关产品推荐
相关产品推荐

