Login State
介绍
LoginState
是一个和登录相关的状态管理中心,专门用于管理登录的状态和操作。它提供了自动登录、手动登录、登出等功能,并支持登录状态的实时监听和错误处理。该 Hook 具备以下特色:
自动登录管理 - 支持传入配置后自动初始化和登录
手动登录控制 - 提供手动登录和登出方法
状态实时同步 - 实时更新登录状态和错误信息
重复登录防护 - 防止重复登录和配置变更时的智能处理
useLoginState 参数
字段 | 类型 | 描述 |
config | LoginConfig | 登录配置 |
config
参数是登录配置,用于初始化登录状态。在组件中直接使用则会自动登录。LoginConfig
定义如下:interface LoginConfig {userID: string; // 用户 IDSDKAppID: number; // 腾讯云应用 IDuserSig: string; // 用户签名onSuccess?: () => void; // 登录成功回调onError?: (error: Error) => void; // 登录失败回调}
useLoginState 返回值
字段 | 类型 | 描述 |
status | LoginStatus | 当前登录状态 |
error | Error | null | 登录过程中的错误信息 |
currentConfig | LoginConfig | null | 当前使用的登录配置 |
login | (config: LoginConfig) => Promise<void> | 手动登录方法 |
logout | () => Promise<void> | 登出方法 |
详细字段说明
status
类型:
LoginStatus
描述: 当前登录状态,用于跟踪登录过程的各个阶段。
枚举定义:
enum LoginStatus {IDLE, // 空闲状态,未开始登录LOADING, // 登录中SUCCESS, // 登录成功ERROR, // 登录失败}
error
类型:
Error | null
描述: 登录过程中发生的错误信息。当登录成功或未发生错误时为
null
。currentConfig
类型:
LoginConfig | null
描述: 当前使用的登录配置信息。用于比较配置变更和防止重复登录。
login
类型:
(config: LoginConfig) => Promise<void>
描述: 手动登录方法。可以传入完整的登录配置进行登录。
参数:
config
- 登录配置对象返回值:
Promise<void>
- 登录完成的 Promiselogout
类型:
() => Promise<void>
描述: 登出方法。清除登录状态并调用 SDK 的登出接口。
返回值:
Promise<void>
- 登出完成的 Promise使用示例
方式一:自动登录(推荐)
这是最简单的使用方式,传入登录配置后会自动初始化并登录:
import React from 'react';import { useLoginState, LoginStatus } from './states/LoginState/LoginState';function App() {const { status, error, logout } = useLoginState({userID: 'your-userID-here',SDKAppID: 0, // your-SDKAppID-here, this is number type!userSig: 'your-userSig-here',onSuccess: () => console.log('🎉 登录成功!'),onError: (error) => console.error('❌ 登录失败:', error),});// 根据登录状态渲染不同内容if (status === LoginStatus.LOADING) {return <div className="loading">登录中...</div>;}if (status === LoginStatus.ERROR) {return (<div className="error"><p>登录失败: {error?.message}</p><button onClick={() => window.location.reload()}>重试</button></div>);}if (status !== LoginStatus.SUCCESS) {return <div className="waiting">等待登录...</div>;}return (<div className="app"><header className="app-header"><h1>聊天应用</h1><button onClick={logout} className="logout-btn">登出</button></header><UIKitProvider></UIKitProvider></div>);}export default App;
方式二:手动控制登录
这种方式提供更多的控制权,可以在需要时手动触发登录:
import React, { useState } from 'react';import { useLoginState, LoginStatus } from './states/LoginState/LoginState';function ManualLoginApp() {const { login, logout, status, error, client } = useLoginState(); // 不传配置const [loginForm, setLoginForm] = useState({userID: '',SDKAppID: 0,userSig: '',});const handleLogin = async () => {try {await login({...loginForm,onSuccess: () => {console.log('登录成功!');// 可以在这里进行登录后的操作},onError: (error) => {console.error('登录失败:', error);// 可以在这里处理登录错误},});} catch (error) {console.error('登录异常:', error);}};const handleLogout = async () => {try {await logout();console.log('登出成功!');} catch (error) {console.error('登出失败:', error);}};const isLoggedIn = status === LoginStatus.SUCCESS;return (<div className="manual-login-app">{!isLoggedIn ? (<div className="login-form"><h2>登录</h2><div className="form-group"><label>用户 ID:</label><inputtype="text"value={loginForm.userID}onChange={(e) => setLoginForm(prev => ({ ...prev, userID: e.target.value }))}placeholder="请输入用户 ID"/></div><div className="form-group"><label>SDK App ID:</label><inputtype="number"value={loginForm.SDKAppID}onChange={(e) => setLoginForm(prev => ({ ...prev, SDKAppID: Number(e.target.value) }))}placeholder="请输入 SDK App ID"/></div><div className="form-group"><label>用户签名:</label><textareavalue={loginForm.userSig}onChange={(e) => setLoginForm(prev => ({ ...prev, userSig: e.target.value }))}placeholder="请输入用户签名"/></div><buttononClick={handleLogin}disabled={status === LoginStatus.LOADING}className="login-btn">{status === LoginStatus.LOADING ? '登录中...' : '登录'}</button>{error && (<div className="error-message">错误: {error.message}</div>)}</div>) : (<div className="app-content"><div className="app-header"><h1>聊天应用</h1><button onClick={handleLogout} className="logout-btn">登出</button></div><ChatApp client={client} /></div>)}</div>);}export default ManualLoginApp;
效果图如下图所示:

样式参考
以下是配套的 SCSS 样式,可以根据需要进行调整:
// 基础样式.loading {display: flex;justify-content: center;align-items: center;height: 100vh;font-size: 18px;color: #666;}.error {display: flex;flex-direction: column;justify-content: center;align-items: center;height: 100vh;p {color: #ff4444;margin-bottom: 16px;}button {padding: 8px 16px;background: #007bff;color: white;border: none;border-radius: 4px;cursor: pointer;&:hover {background: #0056b3;}}}// 应用样式.app {height: 100vh;display: flex;flex-direction: column;.app-header {display: flex;justify-content: space-between;align-items: center;padding: 16px 24px;background: #f8f9fa;border-bottom: 1px solid #e9ecef;h1 {margin: 0;color: #333;}.logout-btn {padding: 8px 16px;background: #dc3545;color: white;border: none;border-radius: 4px;cursor: pointer;&:hover {background: #c82333;}}}}// 手动登录表单样式.manual-login-app {height: 100vh;display: flex;justify-content: center;align-items: center;.login-form {width: 400px;padding: 32px;border: 1px solid #e9ecef;border-radius: 8px;background: white;box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1);h2 {text-align: center;margin-bottom: 24px;color: #333;}.form-group {margin-bottom: 16px;label {display: block;margin-bottom: 4px;color: #555;font-weight: 500;}input, textarea {width: 100%;padding: 8px 12px;border: 1px solid #ddd;border-radius: 4px;font-size: 14px;&:focus {outline: none;border-color: #007bff;}}textarea {height: 80px;resize: vertical;}}.login-btn {width: 100%;padding: 12px;background: #007bff;color: white;border: none;border-radius: 4px;font-size: 16px;cursor: pointer;&:hover:not(:disabled) {background: #0056b3;}&:disabled {background: #ccc;cursor: not-allowed;}}.error-message {margin-top: 12px;padding: 8px;background: #f8d7da;color: #721c24;border-radius: 4px;font-size: 14px;}}}
注意事项
1. 参数验证: 确保传入的
userID
、SDKAppID
和 userSig
都是有效的。2. 错误处理: 始终处理登录可能出现的错误情况。
3. 状态监听: 合理使用登录状态来控制 UI 显示。
4. 资源清理: 在组件卸载时及时调用
logout
方法。5. 安全性: 不要在客户端硬编码敏感信息,
userSig
应该从服务器获取。