Skip to main content

常见问题(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>
);
}

参考:Provider Context

3. 手动创建和销毁控制器的问题

症状: 控制器状态异常、资源未正确释放、或重复创建

原因: 手动使用 createdispose 方法时的生命周期管理不当

解决方案:

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>
);
}

参考:Provider Context - 生命周期管理

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 配置冲突

症状: 同时配置了 agentServiceagentConfig,但 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
};

重要提醒:

  • agentServiceagentConfig 只能选择其一
  • 使用自定义 agentService 时,必须继承 BaseAgentService
  • 检查是否意外传入了 agentService 参数

参考:介绍 - 自定义 AgentService


麦克风设备问题

所有麦克风设备相关的问题(权限、HTTPS 要求、设备占用等)及解决方案,请参考:

👉 Vanilla JS FAQ - 麦克风设备问题排查

该章节包含:

  • 如何检测麦克风是否可用
  • 6 种常见错误的详细解决方案(错误码 3100-3105)
  • 各浏览器的权限设置指南
  • Safari 特殊注意事项
  • 完整的代码示例

所有解决方案同样适用于 React 版本。


更多帮助

相关文档:

技术支持:

联系我们