React中Wishlist切换图标按钮刷新后状态异常求助
解决React心愿单图标刷新后状态重置的问题
问题核心是:组件内的wishlist状态仅存储在内存中,页面刷新后会回到初始值,但Firebase里的持久化数据并未同步到状态里。需要在组件挂载时从Firebase加载已有的心愿单数据,完成wishlist状态的初始化。
步骤1:优化心愿单状态的存储方式
原来用数组索引管理状态容易因房间列表顺序变化出错,改成以房间ID为键的对象,匹配更可靠:
// 替换原来的useState([]) const [wishlist, setWishlist] = useState({});
步骤2:修改图标组件的判断逻辑
不再依赖索引,直接通过房间ID匹配状态:
<i className='text-4xl hrt' onClick={(e)=> AddWishlist(curElm, e)}> {wishlist[curElm.id] && currentUser ? <AiFillHeart /> : <AiOutlineHeart /> } </i>
步骤3:更新点击事件函数
去掉索引参数,基于房间ID修改状态:
// Adding Data to Wishlist const AddWishlist = (curUserData, e) =>{ // 切换当前房间的心愿单状态 const newWishlist = { ...wishlist }; newWishlist[curUserData.id] = !newWishlist[curUserData.id]; setWishlist(newWishlist); if(newWishlist[curUserData.id] === true){ dataref.collection("WishlistWeb").doc(currentUser).collection("wishlistDetails").doc(curUserData.id).set(curUserData) .then(()=>{ toast.success("Added to Wishlist"); }); }else{ dataref.collection("WishlistWeb").doc(currentUser).collection("wishlistDetails").doc(curUserData.id).delete() .then(() => { toast.success("Item Deleted From Wishlist"); }).catch((error) => { console.error('Error Deleting Document', error); }); } }
步骤4:组件挂载时加载Firebase中的心愿单数据
使用useEffect钩子,在用户登录且房间列表加载完成后,将Firebase数据同步到状态:
import { useEffect } from 'react'; // 假设首页房间列表存储在rooms状态中 useEffect(() => { // 用户未登录或房间列表未加载时不执行 if (!currentUser || !rooms.length) return; // 获取当前用户的心愿单数据 dataref.collection("WishlistWeb").doc(currentUser).collection("wishlistDetails") .get() .then((querySnapshot) => { const initialWishlist = {}; // 遍历心愿单文档,标记对应房间ID为已加入 querySnapshot.forEach((doc) => { initialWishlist[doc.id] = true; }); // 更新状态 setWishlist(initialWishlist); }) .catch((error) => { console.error("加载心愿单数据失败: ", error); }); }, [currentUser, rooms]); // 依赖用户状态和房间列表,状态变化时重新加载
关键说明
页面刷新后组件重新挂载,useEffect会自动触发,从Firebase拉取已有的心愿单数据初始化wishlist状态,图标就能正确显示实心/空心状态。同时用房间ID代替索引管理状态,避免房间列表排序、新增后索引错位的问题。
内容的提问来源于stack exchange,提问作者Vivek Fauzdar
相关产品推荐
相关产品推荐

