fix(terminal): resolve React Fast Refresh hook error in usePtyProcess
The hook was using useTerminalStore selectors which can fail during React Fast Refresh (HMR) with 'Should have a queue' errors. This happens because during module hot replacement, React's internal hook queue may not be ready when the component re-initializes. The fix replaces selector-based hook calls: const setTerminalStatus = useTerminalStore((state) => state.setTerminalStatus) With a getState() pattern that doesn't rely on React's hook queue: const getStore = useCallback(() => useTerminalStore.getState(), []) This pattern is already used successfully in useTerminalEvents.ts and other parts of the codebase for accessing Zustand store actions within callbacks. Fixes: AUTO-CLAUDE-1
This commit is contained in:
@@ -28,8 +28,12 @@ export function usePtyProcess({
|
||||
// Trigger state to force re-creation after resetForRecreate()
|
||||
// Refs don't trigger re-renders, so we need a state to ensure the effect runs
|
||||
const [recreationTrigger, setRecreationTrigger] = useState(0);
|
||||
const setTerminalStatus = useTerminalStore((state) => state.setTerminalStatus);
|
||||
const updateTerminal = useTerminalStore((state) => state.updateTerminal);
|
||||
|
||||
// Use getState() pattern for store actions to avoid React Fast Refresh issues
|
||||
// The selectors like useTerminalStore((state) => state.setTerminalStatus) can fail
|
||||
// during HMR with "Should have a queue" errors. Using getState() in callbacks
|
||||
// avoids this by not relying on React's hook queue mechanism.
|
||||
const getStore = useCallback(() => useTerminalStore.getState(), []);
|
||||
|
||||
// Track cwd changes - if cwd changes while terminal exists, trigger recreate
|
||||
useEffect(() => {
|
||||
@@ -80,8 +84,9 @@ export function usePtyProcess({
|
||||
).then((result) => {
|
||||
if (result.success && result.data?.success) {
|
||||
isCreatedRef.current = true;
|
||||
setTerminalStatus(terminalId, terminalState.isClaudeMode ? 'claude-active' : 'running');
|
||||
updateTerminal(terminalId, { isRestored: false });
|
||||
const store = getStore();
|
||||
store.setTerminalStatus(terminalId, terminalState.isClaudeMode ? 'claude-active' : 'running');
|
||||
store.updateTerminal(terminalId, { isRestored: false });
|
||||
onCreated?.();
|
||||
} else {
|
||||
const error = `Error restoring session: ${result.data?.error || result.error}`;
|
||||
@@ -104,7 +109,7 @@ export function usePtyProcess({
|
||||
if (result.success) {
|
||||
isCreatedRef.current = true;
|
||||
if (!alreadyRunning) {
|
||||
setTerminalStatus(terminalId, 'running');
|
||||
getStore().setTerminalStatus(terminalId, 'running');
|
||||
}
|
||||
onCreated?.();
|
||||
} else {
|
||||
@@ -117,7 +122,7 @@ export function usePtyProcess({
|
||||
});
|
||||
}
|
||||
|
||||
}, [terminalId, cwd, projectPath, cols, rows, skipCreation, recreationTrigger, setTerminalStatus, updateTerminal, onCreated, onError]);
|
||||
}, [terminalId, cwd, projectPath, cols, rows, skipCreation, recreationTrigger, getStore, onCreated, onError]);
|
||||
|
||||
// Function to prepare for recreation by preventing the effect from running
|
||||
// Call this BEFORE updating the store cwd to avoid race condition
|
||||
|
||||
Reference in New Issue
Block a user