From 056c44298730e3f48ceafedaa2120a273057838d Mon Sep 17 00:00:00 2001 From: Thanan Traiongthawon <95660+nullcoder@users.noreply.github.com> Date: Sun, 8 Jun 2025 11:20:13 -0700 Subject: [PATCH] perf: optimize Turnstile callbacks to prevent re-renders MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Add useCallback hooks for all Turnstile event handlers in create page - Create stable callback references with empty dependency arrays - Move Turnstile component outside main form content - Fix TypeScript error by adding mockExecute to test suite - Run prettier formatting on all files - Ensures Turnstile widget only renders once, improving performance 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude --- app/create/page.tsx | 62 +++++++++++++++++--------------- components/ui/turnstile.test.tsx | 2 ++ 2 files changed, 35 insertions(+), 29 deletions(-) diff --git a/app/create/page.tsx b/app/create/page.tsx index e77bc70..a7f5f29 100644 --- a/app/create/page.tsx +++ b/app/create/page.tsx @@ -59,6 +59,27 @@ export default function CreateGistPage() { const [turnstileToken, setTurnstileToken] = useState(null); const [isTurnstileReady, setIsTurnstileReady] = useState(false); + // Stable callback references to prevent Turnstile re-renders + const handleTurnstileSuccess = useCallback((token: string) => { + setTurnstileToken(token); + setIsTurnstileReady(true); + }, []); + + const handleTurnstileError = useCallback(() => { + setError( + "🛡️ Security check failed. Please refresh the page and try again." + ); + setIsTurnstileReady(false); + }, []); + + const handleTurnstileExpire = useCallback(() => { + setTurnstileToken(null); + setIsTurnstileReady(false); + setError( + "⏰ Security verification expired. Please refresh the page to continue." + ); + }, []); + const handleFilesChange = useCallback((newFiles: FileData[]) => { setFiles(newFiles); // Don't clear errors on file change - let them persist @@ -321,35 +342,6 @@ export default function CreateGistPage() { - {/* Invisible Turnstile Verification */} - {turnstileSiteKey && ( -
- { - setTurnstileToken(token); - setIsTurnstileReady(true); - }} - onError={() => { - setError( - "🛡️ Security check failed. Please refresh the page and try again." - ); - setIsTurnstileReady(false); - }} - onExpire={() => { - setTurnstileToken(null); - setIsTurnstileReady(false); - setError( - "⏰ Security verification expired. Please refresh the page to continue." - ); - }} - theme="auto" - appearance="interaction-only" - /> -
- )} - {/* Error Display */} {(error || validationMessage) && ( @@ -394,6 +386,18 @@ export default function CreateGistPage() { )} + {/* Invisible Turnstile Verification */} + {turnstileSiteKey && ( + + )} + {/* Share Dialog */} {shareUrl && ( { const mockRender = vi.fn().mockReturnValue("widget-123"); const mockReset = vi.fn(); const mockRemove = vi.fn(); + const mockExecute = vi.fn(); const mockOnSuccess = vi.fn(); const mockOnError = vi.fn(); const mockOnExpire = vi.fn(); @@ -16,6 +17,7 @@ describe("Turnstile", () => { render: mockRender, reset: mockReset, remove: mockRemove, + execute: mockExecute, }; vi.clearAllMocks();