Feliz icon indicating copy to clipboard operation
Feliz copied to clipboard

React 18 in strict mode and useDeferredCallback

Open AkosLukacs opened this issue 2 years ago • 1 comments

Hi! Looks like useDeferredCallback doesn't work with react 18 and strict mode.

Symptoms: upgraded my app to React 18 with strict mode. The UI just hangs, basically nothing happens, and even the network call seems to be cancelled before the server responds. No error thrown, nothing in console. It did work with strict mode & React 17. And does work without strict mode and React 18.

After some digging it looks like the issue might be strict mode in v18 tries to immediately unmount the component and re-mount it. And that triggers the cancellationToken in useDeferredCallback. If I add some logging and an else to the if at https://github.com/Zaid-Ajaj/Feliz/blob/master/Feliz.UseDeferred/UseDeferred.fs#L103 like

            React.useEffectOnce(fun () ->
                React.createDisposable(fun () -> JS.console.log("cancelling..."); cancellationToken.current.Cancel())
            )

            let start = React.useCallbackRef(fun arg ->
                if not cancellationToken.current.IsCancellationRequested
                then Async.StartImmediate(executeOperation arg, cancellationToken.current.Token)
                else JS.console.log("deferred cancelled!", operation)
            )

indeed I get the cancelling and deferred cancelled! message in the console.

Does anybody with more experience with React 18 knows how to solve this? Thanks!

Versions: Fable compiler: 3.7.12

react & react-dom: 18.2.0

Fable.Core (3.7.1) Fable.React (8.0.1) Feliz (1.64) Feliz.UseDeferred (1.4.1)

AkosLukacs avatar Jun 16 '22 09:06 AkosLukacs

Hi there @AkosLukacs, thanks for filing the issue! To be honest, I am not surprised that Feliz.useDeferred doesn't work with React v18.x because they introduced breaking changes with useEffect which useDeferred uses in the implementation.

The current version of Feliz v1.65 and the one you mentioned (v1.64) actually have a strict requirement on React version being: >= 17.0 && < 18.0 as defined in the project settings

    <NpmDependencies>
      <NpmPackage Name="react" Version="&gt;= 17.0.1 &lt; 18.0.0" ResolutionStrategy="Max" />
      <NpmPackage Name="react-dom" Version="&gt;= 17.0.1 &lt; 18.0.0" ResolutionStrategy="Max" />
    </NpmDependencies>

These are npm package requirements

It is expected that upgrading to React v18.x can cause breaking changes. For the time being, consider downgrading to React v17.x until we have updated everything needed: implementations of useEffectOnce(see #480), docs and unit tests

Zaid-Ajaj avatar Jul 09 '22 21:07 Zaid-Ajaj