常见问题(FAQ)
基于 React SDK 文档内容和社区反馈,整理出最重要的问题与解决方案。
1. 开发模式下 mount() 重复调用的 warning
症状: 控制台出现 mount() 重复调用的 warning 提示
原因: 这是 React StrictMode 和 React 19 在开发模式下的正常行为。为了帮助开发者发现副作用问题,React 会故意让 useEffect 执行两次。
解决方案 1:使用清理函数
useEffect(
() => {
if (controller && containerRef.current) {
controller.mount(containerRef.current);
return () => {
controller.dispose();
};
}
},
[controller]
);
解决方案 2:使用 ref 跟踪挂载状态
const mountedRef = useRef(false);
useEffect(
() => {
if (controller && containerRef.current && !mountedRef.current) {
controller.mount(containerRef.current);
mountedRef.current = true;
}
},
[controller]
);
info
这个问题只在开发环境出现,生产环境下不会有此问题。
2. Provider 组件使用误区
症状:useAaaSPilotKit 返回的 controller 一直是 null,或者抛出 Context 错误
原因: 组件没有在 AaaSPilotKitProvider 内部使用,或 Provider 配置错误
解决方案:
// ❌ 错误:组件在 Provider 外部
function App() {
return (
<>
{/* 无法访问 Context */}
<Dashboard />
<AaaSPilotKitProvider options={options}>
<ChatPanel />
</AaaSPilotKitProvider>
</>
);
}
// ✅ 正确:确保所有使用 Hooks 的组件都在 Provider 内部
function App() {
return (
<AaaSPilotKitProvider options={options}>
<Dashboard />
<ChatPanel />
</AaaSPilotKitProvider>
);
}
3. 手动创建和销毁控制器的问题
症状: 控制器状态异常、资源未正确释放、或重复创建
原因: 手动使用 create 和 dispose 方法时的生命周期管理不当
解决方案:
function PilotKit() {
const [isInactive, setIsInactive] = useState(false);
const {controller, create, dispose} = useAaaSPilotKit();
// ✅ 正确的手动生命周期管理
const onInactivity = useCallback(
() => {
setIsInactive(true);
// 手动销毁控制器
dispose();
},
[dispose]
);
const restart = useCallback(
() => {
setIsInactive(false);
// 手动重新创建控制器
create();
},
[create]
);
useAaaSPilotKitEvents({
onInactivity
});
if (isInactive) {
return (
<div>
会话已超时
<button onClick={restart}>
重新开始
</button>
</div>
);
}
return <AvatarComponent />;
}
关键要点:
create()和dispose()用于手动管理控制器生命周期- 调用
dispose()后需要重新create()才能使用 - Provider 通常会自动管理,只在特殊场景下手动控制
常见错误:
// ❌ 错误:dispose 后忘记 create
const handleTimeout = () => {
dispose();
// 缺少 create(),导致 controller 为 null
};
// ❌ 错误:重复 create
const handleRestart = () => {
create(); // 可能导致重复创建
create(); // 重复调用
};
// ❌ 错误:在 dispose 后直接使用 controller
dispose();
controller?.input('test'); // controller 已为 null
// ✅ 正确:等效逻辑
useEffect(
() => {
create();
return dispose;
},
[]
);
参考:Hooks API
4. options 配置导致的频繁重建
症状: 控制器频繁重新创建,或配置更新不生效
原因: options 对象引用不稳定,每次渲染都创建新对象
解决方案:
// ❌ 错误:每次渲染都创建新对象
function App() {
return (
<AaaSPilotKitProvider options={{
token: 'your-auth-token-here',
figureId: '209337',
agentConfig: {token: 'xxx', robotId: 'yyy'}
}}>
<Dashboard />
</AaaSPilotKitProvider>
);
}
// ✅ 正确:使用 useMemo 稳定引用
function App() {
const [robotId, setRobotId] = useState('default-robot');
const options = useMemo(
() => ({
token: 'your-auth-token-here',
figureId: '209337',
ttsPer: 'LITE_audiobook_female_1',
agentConfig: {
robotId: robotId
}
}),
// 只有依赖变化时才重新创建
[robotId]
);
return (
<AaaSPilotKitProvider options={options}>
<Dashboard />
</AaaSPilotKitProvider>
);
}
5. 浏览器自动播放策略导致的音频问题
症状: 初始化后没有声音,或调用播放方法无效果
原因: 浏览器禁止未经用户交互的自动音频播放
解决方案:
function StartButton() {
const {controller, isReady, isMuted} = useAaaSPilotKit();
const handleStart = useCallback(
() => {
if (controller && isReady) {
// ✅ 在用户手势触发后操作音频
controller.mute(false); // 取消静音
controller.input('您好,我是您的数字员工助手');
}
},
[controller, isReady]
);
return (
<button onClick={handleStart} disabled={!isReady}>
{isMuted ? '开启语音对话' : '开始对话'}
</button>
);
}
注意事项:
- 必须在用户手势(点击、触摸等)后才能播放音频
- 确保部署在 HTTPS 环境下
- 移动端浏览器限制更严格
6. AgentService 配置冲突
症状: 同时配置了 agentService 和 agentConfig,但 Agent 连接失败
原因: 自定义 agentService 会覆盖 agentConfig 配置
解决方案:
// ❌ 错误:同时配置会导致 agentConfig 被忽略
const wrongOptions = {
token: 'your-auth-token-here',
figureId: '209337',
agentConfig: {token: 'xxx', robotId: 'yyy'},
agentService: CustomAgentService // 这会覆盖 agentConfig
};
// ✅ 方案1:使用内置 Agent 服务
const builtinOptions = {
token: 'your-auth-token-here',
figureId: '209337',
ttsPer: 'LITE_audiobook_female_1',
agentConfig: {
token: 'your-token',
robotId: 'your-robot-id'
}
};
// ✅ 方案2:使用自定义 Agent 服务
const customOptions = {
token: 'your-auth-token-here',
figureId: '209337',
ttsPer: 'LITE_audiobook_female_1',
agentService: CustomAgentService // 不需要 agentConfig
};
重要提醒:
agentService和agentConfig只能选择其一- 使用自定义
agentService时,必须继承BaseAgentService - 检查是否意外传入了
agentService参数
麦克风设备问题
所有麦克风设备相关的问题(权限、HTTPS 要求、设备占用等)及解决方案,请参考:
该章节包含:
- 如何检测麦克风是否可用
- 6 种常见错误的详细解决方案(错误码 3100-3105)
- 各浏览器的权限设置指南
- Safari 特殊注意事项
- 完整的代码示例
所有解决方案同样适用于 React 版本。
更多帮助
相关文档:
- 快速开始 - 安装配置和基本使用
- Provider Context - Provider 详细配置和高级用法
- Hooks API - 所有 Hooks 的详细参考
- Vanilla SDK 配置选项 - 完整配置项说明
技术支持: