Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
| return { | ||
| info, | ||
| command, | ||
| error, | ||
| success, | ||
| flush, | ||
| } |
There was a problem hiding this comment.
The hook returns a new object literal on every render, causing the object reference to change even though the contained functions are memoized. This will cause the clientLogger dependency in task-page-client.tsx to change on every render, leading to the "Task page loaded in browser" log being recorded multiple times instead of just once.
View Details
📝 Patch Details
diff --git a/lib/hooks/use-client-logger.ts b/lib/hooks/use-client-logger.ts
index 365481f..b754fca 100644
--- a/lib/hooks/use-client-logger.ts
+++ b/lib/hooks/use-client-logger.ts
@@ -1,4 +1,4 @@
-import { useEffect, useRef, useCallback } from 'react'
+import { useEffect, useRef, useCallback, useMemo } from 'react'
import { createClientLogger, ClientLogger } from '@/lib/utils/client-logger'
/**
@@ -65,11 +65,11 @@ export function useClientLogger(taskId: string | null | undefined) {
}
}, [loggerRef])
- return {
+ return useMemo(() => ({
info,
command,
error,
success,
flush,
- }
+ }), [info, command, error, success, flush])
}
Analysis
Object reference changes on every render causes repeated logging in task-page-client
What fails: useClientLogger() returns a new object literal on every render, causing the clientLogger dependency in task-page-client.tsx to change reference every render, which triggers the useEffect to run repeatedly instead of once.
How to reproduce:
// In task-page-client.tsx:
const clientLogger = useClientLogger(taskId)
useEffect(() => {
if (task && clientLogger) {
clientLogger.info('Task page loaded in browser') // Logs multiple times
}
}, [task, clientLogger]) // clientLogger reference changes every renderThis causes the "Task page loaded in browser" message to be logged to the server multiple times when the page loads, instead of just once as intended.
Expected behavior: Per React's useEffect dependency documentation, dependency arrays use reference equality. React's official guidance states that when an object needs to remain stable between renders to prevent Effects from firing excessively, it should be wrapped in useMemo.
Fix: Wrap the returned object in useMemo to maintain referential equality across renders when the contained callback functions haven't changed:
- Added
useMemoto imports - Wrapped the return statement with
useMemoand dependencies[info, command, error, success, flush] - Since all callbacks depend only on the stable
loggerRef, the memoized object maintains identity across renders
No description provided.