From 76313a349abd137276ba944cf2aaea08353484a1 Mon Sep 17 00:00:00 2001 From: Rebecca Williams Date: Mon, 21 Oct 2024 18:18:48 +0100 Subject: [PATCH 1/2] Clean up tasks that lead to state updates on unmounted components This throws warnings as the component is unmounted before state changes can be applied (seen in client tests). Check that component is still mounted before updating state. --- src/ui/widgets/EmbeddedDisplay/useOpiFile.ts | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/src/ui/widgets/EmbeddedDisplay/useOpiFile.ts b/src/ui/widgets/EmbeddedDisplay/useOpiFile.ts index 482ca9a3..90e83edb 100644 --- a/src/ui/widgets/EmbeddedDisplay/useOpiFile.ts +++ b/src/ui/widgets/EmbeddedDisplay/useOpiFile.ts @@ -77,14 +77,17 @@ export function useOpiFile(file: File): WidgetDescription { const fileExt = file.path.split(".").pop() || "json"; const [contents, setContents] = useState(EMPTY_WIDGET); - useEffect((): void => { + useEffect(() => { + let isMounted = false; const fetchData = async (): Promise => { if (fetchPromises.hasOwnProperty(file.path)) { // This resource has been requested; once the cached // promise has been resolved the fileCache should be // populated. await fetchPromises[file.path]; - setContents(fileCache[file.path]); + if (!isMounted) { + setContents(fileCache[file.path]); + } } else { const fetchPromise = fetchAndConvert(file.path, file.defaultProtocol); // Populate the promises cache. @@ -92,10 +95,17 @@ export function useOpiFile(file: File): WidgetDescription { const contents = await fetchPromise; // Populate the file cache. fileCache[file.path] = contents; - setContents(contents); + if (!isMounted) { + setContents(contents); + } } }; fetchData(); + + // Tidy up in case component is unmounted + return () => { + isMounted = true; + }; }, [file.path, file.defaultProtocol, fileExt]); return contents; From 6677fdef2e51cbf8f22662f5bee162bdaa4d47d7 Mon Sep 17 00:00:00 2001 From: Rebecca Williams Date: Tue, 22 Oct 2024 09:04:44 +0100 Subject: [PATCH 2/2] Rename state condition to isMounted --- src/ui/widgets/EmbeddedDisplay/useOpiFile.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/ui/widgets/EmbeddedDisplay/useOpiFile.ts b/src/ui/widgets/EmbeddedDisplay/useOpiFile.ts index 90e83edb..132b6dde 100644 --- a/src/ui/widgets/EmbeddedDisplay/useOpiFile.ts +++ b/src/ui/widgets/EmbeddedDisplay/useOpiFile.ts @@ -78,14 +78,14 @@ export function useOpiFile(file: File): WidgetDescription { const [contents, setContents] = useState(EMPTY_WIDGET); useEffect(() => { - let isMounted = false; + let isMounted = true; const fetchData = async (): Promise => { if (fetchPromises.hasOwnProperty(file.path)) { // This resource has been requested; once the cached // promise has been resolved the fileCache should be // populated. await fetchPromises[file.path]; - if (!isMounted) { + if (isMounted) { setContents(fileCache[file.path]); } } else { @@ -95,7 +95,7 @@ export function useOpiFile(file: File): WidgetDescription { const contents = await fetchPromise; // Populate the file cache. fileCache[file.path] = contents; - if (!isMounted) { + if (isMounted) { setContents(contents); } } @@ -104,7 +104,7 @@ export function useOpiFile(file: File): WidgetDescription { // Tidy up in case component is unmounted return () => { - isMounted = true; + isMounted = false; }; }, [file.path, file.defaultProtocol, fileExt]);