diff --git a/src/components/HTMLLoader.jsx b/src/components/HTMLLoader.jsx index 48908f43..5294f942 100644 --- a/src/components/HTMLLoader.jsx +++ b/src/components/HTMLLoader.jsx @@ -5,6 +5,8 @@ import DOMPurify from 'dompurify'; import { logError } from '@edx/frontend-platform/logging'; +import { useDebounce } from '../discussions/data/hooks'; + const defaultSanitizeOptions = { USE_PROFILES: { html: true }, ADD_ATTR: ['columnalign'], @@ -16,19 +18,21 @@ function HTMLLoader({ const sanitizedMath = DOMPurify.sanitize(htmlNode, { ...defaultSanitizeOptions }); const previewRef = useRef(); + const debouncedPostContent = useDebounce(htmlNode, 500); + useEffect(() => { let promise = Promise.resolve(); // Used to hold chain of typesetting calls - function typeset(code) { promise = promise.then(() => window.MathJax?.typesetPromise(code())) .catch((err) => logError(`Typeset failed: ${err.message}`)); return promise; } - - typeset(() => { - previewRef.current.innerHTML = sanitizedMath; - }); - }, [htmlNode]); + if (debouncedPostContent) { + typeset(() => { + previewRef.current.innerHTML = sanitizedMath; + }); + } + }, [debouncedPostContent]); return (
diff --git a/src/discussions/data/hooks.js b/src/discussions/data/hooks.js index e8df9d49..701d3997 100644 --- a/src/discussions/data/hooks.js +++ b/src/discussions/data/hooks.js @@ -224,3 +224,24 @@ export const useTourConfiguration = (intl) => { } )); }; + +export const useDebounce = (value, delay) => { + // State and setters for debounced value + const [debouncedValue, setDebouncedValue] = useState(value); + useEffect( + () => { + // Update debounced value after delay + const handler = setTimeout(() => { + setDebouncedValue(value); + }, delay); + // Cancel the timeout if value changes (also on delay change or unmount) + // This is how we prevent debounced value from updating if value is changed ... + // .. within the delay period. Timeout gets cleared and restarted. + return () => { + clearTimeout(handler); + }; + }, + [value, delay], // Only re-call effect if value or delay changes + ); + return debouncedValue; +};