From cff1676c69988bdc2b2cd9dedf42abea889ae05d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Krzywizna?= Date: Wed, 28 Feb 2024 14:54:01 +0100 Subject: [PATCH 1/2] Correct the implementation of the dispose function invocation within the `useEffectOnce` hook. --- Feliz/Internal.fs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Feliz/Internal.fs b/Feliz/Internal.fs index 3194d280..d3ac391e 100644 --- a/Feliz/Internal.fs +++ b/Feliz/Internal.fs @@ -87,7 +87,7 @@ module Internal = calledOnce.current <- true destroyFunc.current <- effect() |> Some - if renderAfterCalled.current + if not renderAfterCalled.current then destroyFunc.current else None ) [||] @@ -108,7 +108,7 @@ module Internal = calledOnce.current <- true destroyFunc.current <- effect() - if renderAfterCalled.current + if not renderAfterCalled.current then destroyFunc.current else None ) [||] From 159fc2c0be0ddd667d47f9bb020462a4426d78e6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Krzywizna?= Date: Tue, 26 Mar 2024 08:08:14 +0100 Subject: [PATCH 2/2] Refined `useEffectOnce` to solely act as an alias for `React.useEffect(effect, [||])`, removing logic dependent on double effect invocation in `React.StrictMode` which led to bugs in `IDisposable` overloads. --- Feliz/Internal.fs | 46 +++------------------------------------------- 1 file changed, 3 insertions(+), 43 deletions(-) diff --git a/Feliz/Internal.fs b/Feliz/Internal.fs index d3ac391e..d1da307c 100644 --- a/Feliz/Internal.fs +++ b/Feliz/Internal.fs @@ -63,55 +63,15 @@ module Internal = [] let useEffectOnce(effect: unit -> unit) = - let calledOnce = Interop.reactApi.useRefInternal false - - useEffectWithDeps (fun () -> - if not calledOnce.current then - calledOnce.current <- true - effect() - ) [||] + useEffectWithDeps effect [||] [] let useEffectDisposableOnce (effect: unit -> #IDisposable) = - let destroyFunc = Interop.reactApi.useRefInternal None - let calledOnce = Interop.reactApi.useRefInternal false - let renderAfterCalled = Interop.reactApi.useRefInternal false - - if calledOnce.current then - renderAfterCalled.current <- true - - useEffectDisposableOptWithDeps (fun () -> - if calledOnce.current - then None - else - calledOnce.current <- true - destroyFunc.current <- effect() |> Some - - if not renderAfterCalled.current - then destroyFunc.current - else None - ) [||] + useEffectDisposableOptWithDeps (effect >> Some) [||] [] let useEffectDisposableOptOnce (effect: unit -> #IDisposable option) = - let destroyFunc = Interop.reactApi.useRefInternal None - let calledOnce = Interop.reactApi.useRefInternal false - let renderAfterCalled = Interop.reactApi.useRefInternal false - - if calledOnce.current then - renderAfterCalled.current <- true - - useEffectDisposableOptWithDeps (fun () -> - if calledOnce.current - then None - else - calledOnce.current <- true - destroyFunc.current <- effect() - - if not renderAfterCalled.current - then destroyFunc.current - else None - ) [||] + useEffectDisposableOptWithDeps effect [||] let createContext<'a> (name: string option) (defaultValue: 'a option) =