Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

React 18 UseEffectOnce #480

Closed
JordanMarr opened this issue May 10, 2022 · 1 comment
Closed

React 18 UseEffectOnce #480

JordanMarr opened this issue May 10, 2022 · 1 comment

Comments

@JordanMarr
Copy link
Contributor

JordanMarr commented May 10, 2022

With React 18 bringing a breaking change that will cause React.useEffect to fire twice, it would probably be a good idea to update the Feliz useEffectOnce to prevent breakage.

Here is an adaptation from https://dev.to/ag-grid/react-18-avoiding-use-effect-getting-called-twice-4i9e:

type React =

    member this.useEffectOnce(effect: unit -> unit) = 
        let calledOnce = React.useRef false
                
        React.useEffect (fun () -> 
            if calledOnce.current 
            then ()
            else
                calledOnce.current <- true
                effect()
        , [||])

    member this.useEffectOnce(effect: unit -> IDisposable) = 
        let destroyFunc = React.useRef None
        let calledOnce = React.useRef false
        let renderAfterCalled = React.useRef false

        if calledOnce.current then
            renderAfterCalled.current <- true
        
        React.useEffect (fun () -> 
            if calledOnce.current 
            then None
            else
                calledOnce.current <- true
                destroyFunc.current <- effect() |> Some

                if renderAfterCalled.current
                then destroyFunc.current
                else None
        , [||])

    member this.useEffectOnce(effect: unit -> IDisposable option) = 
        let destroyFunc = React.useRef None
        let calledOnce = React.useRef false
        let renderAfterCalled = React.useRef false

        if calledOnce.current then
            renderAfterCalled.current <- true
        
        React.useEffect (fun () -> 
            if calledOnce.current 
            then None
            else
                calledOnce.current <- true
                destroyFunc.current <- effect()

                if renderAfterCalled.current
                then destroyFunc.current
                else None
        , [||])

Probably needs a bit more work, but that's the idea anyway.

Thoughts?

@Zaid-Ajaj
Copy link
Owner

Implemented in Feliz v2.0 🚀 (which depends on React v18)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants