From 2c91305a6138eca0bd7b4f19645ac4b7b4f717f8 Mon Sep 17 00:00:00 2001 From: Angelo Ashmore Date: Fri, 3 Dec 2021 11:59:26 -1000 Subject: [PATCH] fix: cancel client requests on hook cleanup --- src/useStatefulPrismicClientMethod.ts | 31 +++++++++++++++---- .../useAllPrismicDocumentsByEveryTag.test.tsx | 3 +- test/useAllPrismicDocumentsByIDs.test.tsx | 3 +- .../useAllPrismicDocumentsBySomeTags.test.tsx | 3 +- test/useAllPrismicDocumentsByUIDs.test.tsx | 3 +- test/usePrismicDocumentsByEveryTag.test.tsx | 3 +- test/usePrismicDocumentsByIDs.test.tsx | 3 +- test/usePrismicDocumentsBySomeTags.test.tsx | 3 +- test/usePrismicDocumentsByUIDs.test.tsx | 3 +- 9 files changed, 33 insertions(+), 22 deletions(-) diff --git a/src/useStatefulPrismicClientMethod.ts b/src/useStatefulPrismicClientMethod.ts index 4adedd6..c9ec5af 100644 --- a/src/useStatefulPrismicClientMethod.ts +++ b/src/useStatefulPrismicClientMethod.ts @@ -139,8 +139,14 @@ export const useStatefulPrismicClientMethod = < React.useEffect( () => { + // Used to prevent dispatching an action if the hook was cleaned up. + let didCancel = false; + if (!skip) { - dispatch(["start"]); + if (!didCancel) { + dispatch(["start"]); + } + client[methodName] .call( client, @@ -148,15 +154,28 @@ export const useStatefulPrismicClientMethod = < ...argsWithoutParams, params, ) - .then((result) => dispatch(["succeed", result as TData])) - .catch((error) => dispatch(["fail", error])); + .then((result) => { + if (!didCancel) { + dispatch(["succeed", result as TData]); + } + }) + .catch((error) => { + if (!didCancel) { + dispatch(["fail", error]); + } + }); } + + // Ensure we don't dispatch an action if the hook is cleaned up. + () => { + didCancel = true; + }; }, // We must disable exhaustive-deps since we are using - // JSON.stringify on args (effectively a deep equality check). - // We want this effect to run again anytime args changes. + // JSON.stringify on params (effectively a deep equality check). + // We want this effect to run again anytime params change. // eslint-disable-next-line react-hooks/exhaustive-deps - [client, methodName, JSON.stringify(args)], + [client, methodName, skip, JSON.stringify(params)], ); return React.useMemo( diff --git a/test/useAllPrismicDocumentsByEveryTag.test.tsx b/test/useAllPrismicDocumentsByEveryTag.test.tsx index 0e037c6..67f30fc 100644 --- a/test/useAllPrismicDocumentsByEveryTag.test.tsx +++ b/test/useAllPrismicDocumentsByEveryTag.test.tsx @@ -139,7 +139,6 @@ test.serial("returns failed state on error", async (t) => { oauth_initiate: "oauth_initiate", oauth_token: "oauth_token", }; - const tags = ["tag", "tag2"]; server.use( msw.rest.get(prismic.getEndpoint(md5(t.title)), (_req, res, ctx) => { @@ -148,7 +147,7 @@ test.serial("returns failed state on error", async (t) => { ); const { result, waitForValueToChange } = renderHook( - () => useAllPrismicDocumentsByEveryTag(tags), + () => useAllPrismicDocumentsByEveryTag(["tag", "tag2"]), { wrapper }, ); diff --git a/test/useAllPrismicDocumentsByIDs.test.tsx b/test/useAllPrismicDocumentsByIDs.test.tsx index 094b803..15ee3aa 100644 --- a/test/useAllPrismicDocumentsByIDs.test.tsx +++ b/test/useAllPrismicDocumentsByIDs.test.tsx @@ -139,7 +139,6 @@ test.serial("returns failed state on error", async (t) => { oauth_initiate: "oauth_initiate", oauth_token: "oauth_token", }; - const documentIDs = ["id", "id2"]; server.use( msw.rest.get(prismic.getEndpoint(md5(t.title)), (_req, res, ctx) => { @@ -148,7 +147,7 @@ test.serial("returns failed state on error", async (t) => { ); const { result, waitForValueToChange } = renderHook( - () => useAllPrismicDocumentsByIDs(documentIDs), + () => useAllPrismicDocumentsByIDs(["id", "id2"]), { wrapper }, ); diff --git a/test/useAllPrismicDocumentsBySomeTags.test.tsx b/test/useAllPrismicDocumentsBySomeTags.test.tsx index b791965..4e29e94 100644 --- a/test/useAllPrismicDocumentsBySomeTags.test.tsx +++ b/test/useAllPrismicDocumentsBySomeTags.test.tsx @@ -139,7 +139,6 @@ test.serial("returns failed state on error", async (t) => { oauth_initiate: "oauth_initiate", oauth_token: "oauth_token", }; - const tags = ["tag", "tag2"]; server.use( msw.rest.get(prismic.getEndpoint(md5(t.title)), (_req, res, ctx) => { @@ -148,7 +147,7 @@ test.serial("returns failed state on error", async (t) => { ); const { result, waitForValueToChange } = renderHook( - () => useAllPrismicDocumentsBySomeTags(tags), + () => useAllPrismicDocumentsBySomeTags(["tag", "tag2"]), { wrapper }, ); diff --git a/test/useAllPrismicDocumentsByUIDs.test.tsx b/test/useAllPrismicDocumentsByUIDs.test.tsx index 3963411..fde9322 100644 --- a/test/useAllPrismicDocumentsByUIDs.test.tsx +++ b/test/useAllPrismicDocumentsByUIDs.test.tsx @@ -151,7 +151,6 @@ test.serial("returns failed state on error", async (t) => { oauth_initiate: "oauth_initiate", oauth_token: "oauth_token", }; - const documentUIDs = ["uid1", "uid2"]; server.use( msw.rest.get(prismic.getEndpoint(md5(t.title)), (_req, res, ctx) => { @@ -160,7 +159,7 @@ test.serial("returns failed state on error", async (t) => { ); const { result, waitForValueToChange } = renderHook( - () => useAllPrismicDocumentsByUIDs("type", documentUIDs), + () => useAllPrismicDocumentsByUIDs("type", ["uid1", "uid2"]), { wrapper }, ); diff --git a/test/usePrismicDocumentsByEveryTag.test.tsx b/test/usePrismicDocumentsByEveryTag.test.tsx index 310c789..7d8e5a7 100644 --- a/test/usePrismicDocumentsByEveryTag.test.tsx +++ b/test/usePrismicDocumentsByEveryTag.test.tsx @@ -124,7 +124,6 @@ test.serial("returns failed state on error", async (t) => { oauth_initiate: "oauth_initiate", oauth_token: "oauth_token", }; - const tags = ["tag", "tag2"]; server.use( msw.rest.get(prismic.getEndpoint(md5(t.title)), (_req, res, ctx) => { @@ -133,7 +132,7 @@ test.serial("returns failed state on error", async (t) => { ); const { result, waitForValueToChange } = renderHook( - () => usePrismicDocumentsByEveryTag(tags), + () => usePrismicDocumentsByEveryTag(["tag", "tag2"]), { wrapper }, ); diff --git a/test/usePrismicDocumentsByIDs.test.tsx b/test/usePrismicDocumentsByIDs.test.tsx index 99b2239..4c4d28d 100644 --- a/test/usePrismicDocumentsByIDs.test.tsx +++ b/test/usePrismicDocumentsByIDs.test.tsx @@ -124,7 +124,6 @@ test.serial("returns failed state on error", async (t) => { oauth_initiate: "oauth_initiate", oauth_token: "oauth_token", }; - const documentIDs = ["id", "id2"]; server.use( msw.rest.get(prismic.getEndpoint(md5(t.title)), (_req, res, ctx) => { @@ -133,7 +132,7 @@ test.serial("returns failed state on error", async (t) => { ); const { result, waitForValueToChange } = renderHook( - () => usePrismicDocumentsByIDs(documentIDs), + () => usePrismicDocumentsByIDs(["id", "id2"]), { wrapper }, ); diff --git a/test/usePrismicDocumentsBySomeTags.test.tsx b/test/usePrismicDocumentsBySomeTags.test.tsx index 7e5b808..f9ee45b 100644 --- a/test/usePrismicDocumentsBySomeTags.test.tsx +++ b/test/usePrismicDocumentsBySomeTags.test.tsx @@ -124,7 +124,6 @@ test.serial("returns failed state on error", async (t) => { oauth_initiate: "oauth_initiate", oauth_token: "oauth_token", }; - const tags = ["tag", "tag2"]; server.use( msw.rest.get(prismic.getEndpoint(md5(t.title)), (_req, res, ctx) => { @@ -133,7 +132,7 @@ test.serial("returns failed state on error", async (t) => { ); const { result, waitForValueToChange } = renderHook( - () => usePrismicDocumentsBySomeTags(tags), + () => usePrismicDocumentsBySomeTags(["tag", "tag2"]), { wrapper }, ); diff --git a/test/usePrismicDocumentsByUIDs.test.tsx b/test/usePrismicDocumentsByUIDs.test.tsx index ce2ea53..adca664 100644 --- a/test/usePrismicDocumentsByUIDs.test.tsx +++ b/test/usePrismicDocumentsByUIDs.test.tsx @@ -136,7 +136,6 @@ test.serial("returns failed state on error", async (t) => { oauth_initiate: "oauth_initiate", oauth_token: "oauth_token", }; - const documentUIDs = ["uid1", "uid2"]; server.use( msw.rest.get(prismic.getEndpoint(md5(t.title)), (_req, res, ctx) => { @@ -145,7 +144,7 @@ test.serial("returns failed state on error", async (t) => { ); const { result, waitForValueToChange } = renderHook( - () => usePrismicDocumentsByUIDs("type", documentUIDs), + () => usePrismicDocumentsByUIDs("type", ["uid1", "uid2"]), { wrapper }, );