5.4 KiB
5.4 KiB
useRedDot Hook 使用指南
概述
useRedDot 是一个用于管理应用中红点提示的 React Hook。它提供了完整的红点状态管理功能,默认显示红点,查看后消失。
特性
- ✅ 默认显示逻辑:localStorage 不存在记录时显示红点
- ✅ 自动持久化:使用 localStorage 存储已查看状态
- ✅ 一次性显示:查看后自动消失
- ✅ 命名空间隔离:通过前缀避免键名冲突
- ✅ 批量操作:支持批量标记已读和清除
- ✅ TypeScript 支持:完整的类型定义
基本用法
1. 导入 Hook
import { useRedDot, RED_DOT_KEYS } from '@/hooks/useRedDot';
2. 在组件中使用
const MyComponent = () => {
const { hasRedDot, markAsViewed, showRedDot } = useRedDot({
prefix: 'my_feature_' // 可选,默认为 'red_dot_'
});
return (
<div>
<div className="flex items-center gap-2">
<span>设置</span>
{hasRedDot('settings') && <Badge variant="dot" />}
</div>
<button onClick={() => markAsViewed('settings')}>
查看设置
</button>
</div>
);
};
API 参考
参数
interface UseRedDotOptions {
prefix?: string; // localStorage 键名前缀,默认 'red_dot_'
}
返回值
interface UseRedDotReturn {
// 检查是否显示红点
hasRedDot: (key: string) => boolean;
// 标记为已查看(消除红点)
markAsViewed: (key: string) => void;
// 显示红点
showRedDot: (key: string) => void;
// 批量标记已查看
markMultipleAsViewed: (keys: string[]) => void;
// 清除所有红点
clearAllRedDots: () => void;
// 获取所有有红点的功能键
getAllRedDotKeys: () => string[];
}
预定义常量
为了避免硬编码字符串,提供了预定义的红点键:
export const RED_DOT_KEYS = {
CHAT_BUBBLE: 'chat_bubble',
CHAT_BACKGROUND: 'chat_background',
CHAT_MODEL: 'chat_model',
PROFILE_SETTING: 'profile_setting',
} as const;
完整示例
聊天设置页面
import { useRedDot, RED_DOT_KEYS } from '@/hooks/useRedDot';
import { Badge } from '@/components/ui/badge';
const ChatSettingsPage = () => {
const { hasRedDot, markAsViewed } = useRedDot({
prefix: `chat_${chatId}_`
});
const handleBubbleSettingClick = () => {
// 点击时标记为已查看
markAsViewed(RED_DOT_KEYS.CHAT_BUBBLE);
// 打开设置页面
openBubbleSettings();
};
return (
<div>
<div className="setting-item" onClick={handleBubbleSettingClick}>
<div className="flex items-center gap-2">
<span>聊天气泡</span>
{hasRedDot(RED_DOT_KEYS.CHAT_BUBBLE) && <Badge variant="dot" />}
</div>
</div>
<div className="setting-item" onClick={() => {
markAsViewed(RED_DOT_KEYS.CHAT_BACKGROUND);
openBackgroundSettings();
}}>
<div className="flex items-center gap-2">
<span>聊天背景</span>
{hasRedDot(RED_DOT_KEYS.CHAT_BACKGROUND) && <Badge variant="dot" />}
</div>
</div>
</div>
);
};
管理页面(显示红点)
const AdminPage = () => {
const { showRedDot } = useRedDot();
const handleNewFeatureRelease = () => {
// 发布新功能时显示红点
showRedDot(RED_DOT_KEYS.CHAT_BUBBLE);
showRedDot(RED_DOT_KEYS.CHAT_BACKGROUND);
};
return (
<button onClick={handleNewFeatureRelease}>
发布聊天新功能
</button>
);
};
高级用法
1. 不同用户/场景的隔离
// 为不同用户使用不同前缀
const userARedDot = useRedDot({ prefix: `user_${userA.id}_` });
const userBRedDot = useRedDot({ prefix: `user_${userB.id}_` });
// 为不同功能模块使用不同前缀
const chatRedDot = useRedDot({ prefix: 'chat_' });
const profileRedDot = useRedDot({ prefix: 'profile_' });
2. 批量操作
const { markMultipleAsViewed, clearAllRedDots } = useRedDot();
// 用户查看了整个设置页面,标记多个功能为已读
const handleSettingsPageVisit = () => {
markMultipleAsViewed([
RED_DOT_KEYS.CHAT_BUBBLE,
RED_DOT_KEYS.CHAT_BACKGROUND,
RED_DOT_KEYS.CHAT_MODEL
]);
};
// 重置所有红点(比如用户重新登录)
const handleUserLogin = () => {
clearAllRedDots();
};
3. 状态监控
const { getAllRedDotKeys, hasRedDot } = useRedDot();
// 获取当前所有未读功能
const unreadFeatures = getAllRedDotKeys();
console.log('用户有', unreadFeatures.length, '个未读功能');
// 检查是否有任何未读
const hasAnyUnread = unreadFeatures.length > 0;
注意事项
- localStorage 限制:确保浏览器支持 localStorage
- 前缀命名:使用有意义的前缀避免冲突
- 性能考虑:避免在 render 方法中频繁调用 showRedDot
- 错误处理:Hook 内部已处理 localStorage 异常
存储格式
红点状态在 localStorage 中的存储格式:
键名: ${prefix}${redDotKey}
值: 'viewed' | undefined (删除)
重要逻辑:
- 不存在记录 = 显示红点(默认状态)
- 存在 'viewed' 记录 = 不显示红点(已查看)
例如:
- 无记录 -> 显示红点
chat_123_chat_bubble: 'viewed'-> 不显示红点profile_settings: 'viewed'-> 不显示红点