React中实现关注状态切换按钮文本及刷新后状态保持
解决React关注/取消关注按钮刷新后状态不保持问题
核心问题出在组件刷新时,useState的初始状态没有同步localStorage中已更新的followers数据,导致按钮判断逻辑基于旧的状态渲染文本。下面是具体的修复方案:
1. 修正状态初始化逻辑
组件挂载时,优先从localStorage读取目标用户的followers数据,而非仅依赖API返回的初始值:
import { useState, useEffect } from 'react'; // 若需从JWT解析user_id,可引入jwt-decode(自行安装) // import jwtDecode from 'jwt-decode'; const UserProfile = () => { // 获取当前登录用户ID const token = localStorage.getItem('jwt'); const currentUserId = token ? JSON.parse(atob(token.split('.')[1])).user_id : null; // 手动解析JWT,或用jwt-decode const [profile, setProfile] = useState(null); useEffect(() => { const fetchProfile = async () => { // 调用API获取目标用户基础信息 const res = await fetch(`/api/user/${targetUserId}`); // 替换为你的API地址 const fetchedProfile = await res.json(); // 从localStorage读取已保存的followers(用目标用户ID做key,避免多用户冲突) const savedFollowers = localStorage.getItem(`followers_${fetchedProfile.user_id}`); if (savedFollowers) { // 用localStorage的最新followers覆盖API返回值 setProfile({ ...fetchedProfile, followers: JSON.parse(savedFollowers) }); } else { // 首次加载时,把API返回的followers存入localStorage setProfile(fetchedProfile); localStorage.setItem(`followers_${fetchedProfile.user_id}`, JSON.stringify(fetchedProfile.followers)); } }; fetchProfile(); }, [targetUserId]); // targetUserId需根据你的组件逻辑传入
2. 优化关注切换逻辑
确保每次切换状态时,同步更新state和localStorage,且基于当前状态判断按钮文本:
const handleFollowToggle = async () => { if (!profile || !currentUserId) return; const isFollowing = profile.followers.includes(currentUserId); let updatedFollowers; try { if (isFollowing) { // 取消关注:从followers移除当前用户ID updatedFollowers = profile.followers.filter(id => id !== currentUserId); await fetch(`/api/user/${profile.user_id}/unfollow`, { method: 'POST' }); } else { // 关注:添加当前用户ID到followers updatedFollowers = [...profile.followers, currentUserId]; await fetch(`/api/user/${profile.user_id}/follow`, { method: 'POST' }); } // 更新组件状态 setProfile(prev => ({ ...prev, followers: updatedFollowers })); // 同步更新localStorage localStorage.setItem(`followers_${profile.user_id}`, JSON.stringify(updatedFollowers)); } catch (err) { // API调用失败时,可添加错误提示或回滚状态 console.error('关注操作失败:', err); } };
3. 动态渲染按钮文本
用一个按钮替代两个独立按钮,根据当前followers状态动态切换文本:
{profile && currentUserId && ( <button onClick={handleFollowToggle} className="follow-btn"> {profile.followers.includes(currentUserId) ? '取消关注' : '关注'} </button> )}
关键注意事项
- 存储followers时,必须用目标用户ID作为localStorage的key,避免多个用户的关注状态互相覆盖。
- 若API调用失败,需处理错误回滚,防止localStorage与后端数据不一致。
- 若JWT存储在localStorage,解析user_id时要注意安全性(避免XSS风险,可考虑将敏感数据存在HttpOnly Cookie)。
内容的提问来源于stack exchange,提问作者Destiny Franks
相关产品推荐
相关产品推荐

