如何修复React中类似Instagram点赞功能的分支判断异常
修复Instagram风格点赞/取消点赞功能的分支判断问题
问题核心
当前代码存在三个关键问题导致点击按钮总是进入点赞分支:
userLikedPhotos初始为空对象,未从gridData同步初始点赞状态,导致判断条件永远为假- 使用用户ID作为
userLikedPhotos的键不合理,同一个用户的多张照片可独立点赞,应使用照片ID作为唯一标识 - 直接修改原状态对象/数组(如
delete userLikedPhotos[likedPhotoUserId]、修改gridData元素的likes)违反React状态不可变原则,会导致状态更新不生效或异常
修复步骤
- 初始化同步点赞状态:获取
gridData后,将每张照片的点赞状态同步到userLikedPhotos,用照片ID作为键 - 修正判断逻辑:根据照片ID判断当前是否已点赞,而非用户ID
- 遵循状态不可变原则:修改状态时创建新的对象/数组副本,不直接修改原状态
修改后的完整代码
const Grid = () => { const authToken = localStorage.getItem('token'); const [gridData, setGridData] = useState([]); const [userLikedPhotos, setUserLikedPhotos] = useState({}); useEffect(() => { const headers = { "Accept": 'application/json', "Authorization": `Bearer ${authToken}` }; axios.get('http://127.0.0.1:8000/api/get-user-uploads-data', {headers}) .then(resp => { const data = resp.data; setGridData(data); // 初始化同步已点赞状态,用photo_id作为唯一标识键 const initialLikedState = {}; data.forEach(photo => { if (photo.is_liked) { initialLikedState[photo.photo_id] = true; } }); setUserLikedPhotos(initialLikedState); }).catch(err => { console.log(err); }); }, []); const handleLikesBasedOnUserId = (likedPhotoUserId, userName, likedPhotoId) => { // 基于照片ID判断当前是否已点赞 if (userLikedPhotos[likedPhotoId]) { // 取消点赞逻辑 handleDislike(likedPhotoUserId, userName, likedPhotoId); // 创建新状态副本,删除对应照片的点赞记录 const newUserLikedPhotos = {...userLikedPhotos}; delete newUserLikedPhotos[likedPhotoId]; setUserLikedPhotos(newUserLikedPhotos); // 更新gridData,同步点赞数和状态 setGridData(prevData => prevData.map(photo => { if (photo.photo_id === likedPhotoId) { return {...photo, likes: photo.likes - 1, is_liked: false}; } return photo; })); console.log("Disliked"); } else { // 点赞逻辑 handleLike(likedPhotoUserId, userName, likedPhotoId); // 创建新状态副本,添加对应照片的点赞记录 setUserLikedPhotos(prev => ({...prev, [likedPhotoId]: true})); // 更新gridData,同步点赞数和状态 setGridData(prevData => prevData.map(photo => { if (photo.photo_id === likedPhotoId) { return {...photo, likes: photo.likes + 1, is_liked: true}; } return photo; })); console.log("Liked"); } }; return ( <> <div className="img-container"> {gridData.map((photo, index) => ( <div key={photo.photo_id} className="userDetails"> <span className="likesAmt">❤️ {photo.likes}</span> <Button variant={photo.is_liked ? 'danger' : 'success'} onClick={() => handleLikesBasedOnUserId(photo.UserID, photo.name, photo.photo_id)} > {photo.is_liked ? 'Dislike' : 'Like'} </Button> </div> ))} </div> </> ) } export default Grid;
关键修改说明
- 在
useEffect中初始化userLikedPhotos:遍历gridData,将已点赞的照片ID作为键存入状态,确保初始判断准确 - 用
photo_id代替用户ID作为userLikedPhotos的键,解决同一用户多张照片的独立点赞问题 - 修改状态时均创建新的对象/数组副本(展开运算符、
map方法),遵循React状态不可变原则,确保状态更新触发组件重新渲染 - 更新
gridData时同步修改is_liked和likes字段,保证UI显示与状态实时一致
内容的提问来源于stack exchange,提问作者sp92
相关产品推荐
相关产品推荐

