From 99508d8e03863dbf7e969edd004f085db5b8e93e Mon Sep 17 00:00:00 2001 From: Abi Raja Date: Wed, 15 Nov 2023 09:51:34 -0500 Subject: [PATCH] throttle the iframe preview so that it doesn't stop updating at the end of code generation due to too many updates --- frontend/src/components/Preview.tsx | 8 ++++++-- frontend/src/hooks/useThrottle.ts | 28 ++++++++++++++++++++++++++++ 2 files changed, 34 insertions(+), 2 deletions(-) create mode 100644 frontend/src/hooks/useThrottle.ts diff --git a/frontend/src/components/Preview.tsx b/frontend/src/components/Preview.tsx index de8c36f..4728a73 100644 --- a/frontend/src/components/Preview.tsx +++ b/frontend/src/components/Preview.tsx @@ -1,13 +1,17 @@ +import useThrottle from "../hooks/useThrottle"; + interface Props { code: string; } function Preview({ code }: Props) { + const throttledCode = useThrottle(code, 200); + return (
diff --git a/frontend/src/hooks/useThrottle.ts b/frontend/src/hooks/useThrottle.ts new file mode 100644 index 0000000..c9f4fcc --- /dev/null +++ b/frontend/src/hooks/useThrottle.ts @@ -0,0 +1,28 @@ +import React from "react"; + +// Updates take effect immediately if the last update was more than {interval} ago. +// Otherwise, updates are throttled to {interval}. The latest value is always sent. +// The last update always gets executed, with potentially a {interval} delay. +export function useThrottle(value: string, interval = 500) { + const [throttledValue, setThrottledValue] = React.useState(value); + const lastUpdated = React.useRef(null); + + React.useEffect(() => { + const now = Date.now(); + + if (!lastUpdated.current || now >= lastUpdated.current + interval) { + lastUpdated.current = now; + setThrottledValue(value); + } else { + const id = window.setTimeout(() => { + lastUpdated.current = now; + setThrottledValue(value); + }, interval); + + return () => window.clearTimeout(id); + } + }, [value, interval]); + + return throttledValue; +} +export default useThrottle;