FAQ (Frequently Asked Questions)
Based on React SDK documentation content and community feedback, the most important questions and solutions are compiled.
1. mount() Repeated Call Warning in Development Mode
Symptom: Console shows warning about repeated mount() calls
Cause: This is normal behavior of React StrictMode and React 19 in development mode. To help developers discover side effect issues, React intentionally executes useEffect twice.
Solution 1: Use Cleanup Function
useEffect(
() => {
if (controller && containerRef.current) {
controller.mount(containerRef.current);
return () => {
controller.dispose();
};
}
},
[controller]
);
Solution 2: Use ref to Track Mount State
const mountedRef = useRef(false);
useEffect(
() => {
if (controller && containerRef.current && !mountedRef.current) {
controller.mount(containerRef.current);
mountedRef.current = true;
}
},
[controller]
);
This issue only appears in development environment, and will not occur in production environment.
2. Provider Component Usage Pitfalls
Symptom: controller returned by useAaaSPilotKit is always null, or throws Context error
Cause: Component is not used inside AaaSPilotKitProvider, or Provider configuration is wrong
Solution:
// ❌ Error: Component outside Provider
function App() {
return (
<>
{/* Cannot access Context */}
<Dashboard />
<AaaSPilotKitProvider options={options}>
<ChatPanel />
</AaaSPilotKitProvider>
</>
);
}
// ✅ Correct: Ensure all components using Hooks are inside Provider
function App() {
return (
<AaaSPilotKitProvider options={options}>
<Dashboard />
<ChatPanel />
</AaaSPilotKitProvider>
);
}
Reference: Provider Context
3. Issues with Manual Controller Creation and Destruction
Symptom: Abnormal controller state, resources not properly released, or repeated creation
Cause: Improper lifecycle management when manually using create and dispose methods
Solution:
function PilotKit() {
const [isInactive, setIsInactive] = useState(false);
const {controller, create, dispose} = useAaaSPilotKit();
// ✅ Correct manual lifecycle management
const onInactivity = useCallback(
() => {
setIsInactive(true);
// Manually destroy controller
dispose();
},
[dispose]
);
const restart = useCallback(
() => {
setIsInactive(false);
// Manually re-create controller
create();
},
[create]
);
useAaaSPilotKitEvents({
onInactivity
});
if (isInactive) {
return (
<div>
Session timed out
<button onClick={restart}>
Restart
</button>
</div>
);
}
return <AvatarComponent />;
}
Key Points:
create()anddispose()are used for manual controller lifecycle management- After calling
dispose(), need tocreate()again before using - Provider usually manages automatically, only manually control in special scenarios
Common Errors:
// ❌ Error: Forget to create after dispose
const handleTimeout = () => {
dispose();
// Missing create(), causing controller to be null
};
// ❌ Error: Repeated create
const handleRestart = () => {
create(); // May cause repeated creation
create(); // Repeated call
};
// ❌ Error: Use controller directly after dispose
dispose();
controller?.input('test'); // controller is already null
// ✅ Correct: Equivalent logic
useEffect(
() => {
create();
return dispose;
},
[]
);
Reference: Hooks API
4. Frequent Re-reconstruction Caused by options Configuration
Symptom: Controller frequently re-creates, or configuration updates don't take effect
Cause: options object reference is unstable, creating new object on every render
Solution:
// ❌ Error: Create new object on every render
function App() {
return (
<AaaSPilotKitProvider options={{
token: 'your-auth-token-here',
figureId: '209337',
agentConfig: {token: 'xxx', robotId: 'yyy'}
}}>
<Dashboard />
</AaaSPilotKitProvider>
);
}
// ✅ Correct: Use useMemo to stabilize reference
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
}
}),
// Only re-create when dependency changes
[robotId]
);
return (
<AaaSPilotKitProvider options={options}>
<Dashboard />
</AaaSPilotKitProvider>
);
}
Reference: Provider Context - Lifecycle Management
5. Audio Issues Caused by Browser Autoplay Policy
Symptom: No sound after initialization, or calling playback methods has no effect
Cause: Browsers prohibit automatic audio playback without user interaction
Solution:
function StartButton() {
const {controller, isReady, isMuted} = useAaaSPilotKit();
const handleStart = useCallback(
() => {
if (controller && isReady) {
// ✅ Operate audio after user gesture trigger
controller.mute(false); // Unmute
controller.input('Hello, I am your digital employee assistant');
}
},
[controller, isReady]
);
return (
<button onClick={handleStart} disabled={!isReady}>
{isMuted ? 'Start Voice Conversation' : 'Start Conversation'}
</button>
);
}
Notes:
- Audio can only be played after user gesture (click, touch, etc.)
- Ensure deployment in HTTPS environment
- Mobile browsers have stricter restrictions
6. AgentService Configuration Conflict
Symptom: Both agentService and agentConfig configured, but Agent connection fails
Cause: Custom agentService will override agentConfig configuration
Solution:
// ❌ Error: Configuring both will cause agentConfig to be ignored
const wrongOptions = {
token: 'your-auth-token-here',
figureId: '209337',
agentConfig: {token: 'xxx', robotId: 'yyy'},
agentService: CustomAgentService // This will override agentConfig
};
// ✅ Solution 1: Use built-in Agent service
const builtinOptions = {
token: 'your-auth-token-here',
figureId: '209337',
ttsPer: 'LITE_audiobook_female_1',
agentConfig: {
token: 'your-token',
robotId: 'your-robot-id'
}
};
// ✅ Solution 2: Use custom Agent service
const customOptions = {
token: 'your-auth-token-here',
figureId: '209337',
ttsPer: 'LITE_audiobook_female_1',
agentService: CustomAgentService // agentConfig not needed
};
Important Reminders:
- Can only choose one between
agentServiceandagentConfig - When using custom
agentService, must inherit fromBaseAgentService - Check if
agentServiceparameter was accidentally passed in
Reference: Introduction - Custom AgentService
Microphone Device Issues
All microphone device-related issues (permissions, HTTPS requirements, device occupancy, etc.) and solutions, please refer to:
👉 Vanilla JS FAQ - Microphone Device Troubleshooting
This chapter includes:
- How to check if microphone is available
- Detailed solutions for 6 common errors (error codes 3100-3105)
- Browser permission setting guides
- Safari special considerations
- Complete code examples
All solutions are equally applicable to React version.
More Help
Related Documentation:
- Quick Start - Installation configuration and basic usage
- Provider Context - Provider detailed configuration and advanced usage
- Hooks API - Detailed reference for all Hooks
- Vanilla SDK Configuration Options - Complete configuration item description
Technical Support:
- Email: zhangwenxi@baidu.com, lifuxin@baidu.com, hanbowen01@baidu.com
- See more: Vanilla SDK Documentation