React Native中Firebase Realtime Database更新后跳转未等待,详情页显示旧数据
问题根源
- 核心错误是
then()回调的写法错误:你直接将navigation.navigate("Details", { id: itemId })作为参数传给then(),这会导致跳转逻辑同步立即执行,不会等待Firebase的set操作完成。只有给then()传入一个函数,才会在Promise resolve之后执行对应逻辑。 - 次要原因是Firebase Realtime Database的
get()方法默认优先读取本地离线缓存,刚完成写入操作时本地缓存可能还没同步,会返回旧数据。 - 详情页的
useEffect没有将id加入依赖数组,若后续id发生变化不会重新触发数据拉取。
修复步骤
1. 修正保存逻辑的Promise回调写法
推荐使用async/await写法更易读,避免回调嵌套错误:
const saveExisting = async (data) => { try { await Firebase.database() .ref("users/" + user.uid + "/items/" + itemId) .set(data); console.log("Item Updated"); // 确认写入成功后再跳转 navigation.navigate("Details", { id: itemId }); } catch (error) { console.log("Error saving existing item", error); } };
如果偏好Promise链式写法,需要给then传入回调函数:
const saveExisting = (data) => { Firebase.database() .ref("users/" + user.uid + "/items/" + itemId) .set(data) .then(() => { console.log("Item Updated"); navigation.navigate("Details", { id: itemId }); }) .catch((error) => { console.log("Error saving existing item", error); }); };
注:不需要同时给set传回调函数又用then,二者选其一即可,重复写容易出现逻辑冲突。
2. 修正详情页数据拉取逻辑
优先使用once('value')替代get(),能保证拿到最新同步后的数据,同时将id加入useEffect依赖数组:
const [title, setTitle] = useState(""); useEffect(() => { const itemRef = Firebase.database() .ref("users/" + user.uid + "/items/" + id); itemRef.once('value') .then((snapshot) => { if (snapshot.exists()) { snapshot.val().name && setTitle(snapshot.val().name); } else { console.log("No data found"); } }) .catch((error) => { console.log("error: " + error); }); }, [id]); // id加入依赖,变化时自动重新拉取
如果需要实现数据实时更新,可改用持久化监听,后续数据修改会自动同步到页面:
const [title, setTitle] = useState(""); useEffect(() => { const itemRef = Firebase.database() .ref("users/" + user.uid + "/items/" + id); const handleValueChange = (snapshot) => { if (snapshot.exists()) { snapshot.val().name && setTitle(snapshot.val().name); } else { console.log("No data found"); } }; // 注册数据变化监听 itemRef.on('value', handleValueChange, (error) => { console.log("error: " + error); }); // 组件卸载时移除监听,避免内存泄漏 return () => itemRef.off('value', handleValueChange); }, [id]);
内容的提问来源于stack exchange,提问作者jpsnow72
相关产品推荐
相关产品推荐

