React点赞系统如何实现各对象独立的currentUserClicks状态
问题本质
你当前使用单个全局变量currentUserClicks存储用户点击状态,所有照片的点赞判断都依赖这同一个值,无法区分用户点击的是哪张照片,才会出现点击A之后再点B误触发取消点赞的问题。
修复方案
点赞本身是和具体照片绑定的独立状态,不要用单个全局数值存储,推荐以下两种实现方式,优先选第一种,逻辑更简洁:
- 用
Set存储当前用户已点赞的所有照片ID,判断某张照片是否已点赞时,直接检查ID是否在Set中即可,完全匹配点赞/取消赞的二元交互逻辑,不需要额外维护点击计数。 - 如果确实需要保留点击计数逻辑,用对象做状态映射,以照片ID为key,每个key对应存储单张照片的用户点击次数,实现状态隔离。
推荐实现(Set存储已点赞ID)
// 初始化存储已点赞照片ID的Set const [likedPhotoIds, setLikedPhotoIds] = useState(new Set()); const handleLikesBasedOnUserId = (likedPhotoUserId) => { const hasLiked = likedPhotoIds.has(likedPhotoUserId); if (hasLiked) { // 已点赞状态点击则取消点赞 setLikedPhotoIds(prev => { const nextSet = new Set(prev); nextSet.delete(likedPhotoUserId); return nextSet; }); handleDislike(likedPhotoUserId); } else { // 未点赞状态点击则新增点赞 setLikedPhotoIds(prev => { const nextSet = new Set(prev); nextSet.add(likedPhotoUserId); return nextSet; }); handleLike(likedPhotoUserId); } }; // 渲染单张照片时,直接通过ID判断当前用户是否已点赞即可 // const isCurrentUserLiked = likedPhotoIds.has(photo.id)
备选实现(映射表存储单图点击次数)
如果要保留原有点击计数的判断逻辑,把单值状态改成ID映射的对象即可:
// key为照片ID,value为当前用户对该照片的点击次数 const [userClicksMap, setUserClicksMap] = useState({}); const handleLikesBasedOnUserId = (likedPhotoUserId) => { const currentClicks = userClicksMap[likedPhotoUserId] ?? 0; if (currentClicks >= 1) { setUserClicksMap(prev => ({ ...prev, [likedPhotoUserId]: currentClicks - 1 })); handleDislike(likedPhotoUserId); } else { setUserClicksMap(prev => ({ ...prev, [likedPhotoUserId]: currentClicks + 1 })); handleLike(likedPhotoUserId); } };
注意:更新状态时建议使用函数式入参(即示例中传入
prev的写法),避免闭包缓存旧状态值导致计数异常。
内容的提问来源于stack exchange,提问作者luvs2spooge
相关产品推荐
相关产品推荐

