Zaid-Ajaj / Feliz.Router

A router component for React and Elmish that is focused, powerful and extremely easy to use.
MIT License
77 stars 16 forks source link

Issue version 3.10.0 when using another Router component in the inner component #67

Open sayyaari opened 1 year ago

sayyaari commented 1 year ago

We have an elmish app uses Fable 3.1.9 and following packages:


  <ItemGroup>
    <PackageReference Include="Fable.Elmish.React" Version="3.0.1" />
    <PackageReference Include="Fable.React" Version="7.2.0" />
    <PackageReference Include="Feliz.Router" Version="3.7.0" />
    <PackageReference Include="Feliz.UseDeferred" Version="1.4.1" />
    <PackageReference Include="Thoth.Json" Version="7.0.0" />
  </ItemGroup>
  <ItemGroup>
    <PackageReference Update="FSharp.Core" Version="5.0.1" />
  </ItemGroup>

This app uses a web component which was written in a separate project and will be injected as web component though the following api: domEl "Component-X" ...

That component references the following packages:

  <ItemGroup>
    <PackageReference Include="Fable.Elmish.React" Version="3.0.1" />
    <PackageReference Include="Fable.React" Version="7.4.0" />
    <PackageReference Include="Fable.SimpleHttp" Version="3.5.0" />
    <PackageReference Include="Feliz.Router" Version="3.10.0" />
    <PackageReference Include="Feliz.UseDeferred" Version="1.5.0" />
    <PackageReference Include="Feliz.UseElmish" Version="1.5.1" />
  </ItemGroup>
  <ItemGroup>
    <PackageReference Update="FSharp.Core" Version="7.0.200" />
  </ItemGroup>

Component-X uses its own routing and recently we upgraded the its packages to upgraded the Feliz.Router to 3.10.0 of Feliz.Router.

After upgrading we found out that the routing at the application level doesn't work as before. Once the app navigated to Component-X and , from that time onward any url changes at the application level will raise two Router Url Changed events. One at the application level 's Router and the other at the Component-X 's Router level which interestingly the Url that is passed to the latter one is different from the one that is captured at application level. The url captured at Component-X level is base route of the component. Let say we have the following routes at the application level /path1 /path2 /Component-X

and the followings routes at the Component-X /Component-X /Component-X/Path3 /Component-X/Path4

When the app is loaded the routing to /path1 and /path3 (assume that the navigations are done through some hyperlinks) work correctly as long as we haven't touched any navigationto Component-X. If we navigate to Component-X (Component-X is rendered ) then those hyperlinks which previously navigated us to /path1 and /path2 now navigate to Component-X. If for example, you click the hyperlink that navigates you to /path1 then UrlChanged event occurs at App Router level and has the value /path1 and surprisingly the UrlChanged event happens at Component-X router level but with value /Component-X. In other versions before 3.10 the second UrlChanged event doesn't happen.

Per my investigation this error happens when the Component-X references just Feliz.Router 3.10.0 and all the other versions before that work correctly.

I can see that in the version 3.10.0 there is a major change to "No longer rely on Feliz.UseListener" and I am afraid that with this change we will face the same problem when we upgrade our app and components to fable version 4.0 in future.

Is it a bug with Feliz.Router version 3.10 upward or I need to change something in my App or Component?

Zaid-Ajaj commented 1 year ago

Hi here @sayyaari I would like to investigate this issue more but would need a minimal repro to debug it.

from that time onward any url changes at the application level will raise two Router Url Changed events.

Since the fix for #50 I had a change made to the router component such that it triggers onUrlChanged when the component mounts. This might be the reason for the double triggers (one from Component-X and one from the application level).

which interestingly the Url that is passed to the latter one is different from the one that is captured at application level. The url captured at Component-X level is base route of the component.

That is unexpected indeed. The URLs are always derived the same way so they should be the same, that is unless one component is using router.pathMode and the other is using hash routing (path after the # sign)

I can we can fix the issue with the double triggers by using an option such as router.triggerOnMount false but it seems a bit hacky.

I can see that in the version 3.10.0 there is a major change to "No longer rely on Feliz.UseListener" and I am afraid that with this change we will face the same problem when we upgrade our app and components to fable version 4.0 in future.

This was not a breaking change since I simply took the implementation of a single hook from there and moved it here so that I no longer rely on the entire library

Is it a bug with Feliz.Router version 3.10 upward or I need to change something in my App or Component?

I can't say for sure unless I have an example to work with and debug

sayyaari commented 1 year ago

Thanks @Zaid-Ajaj for the detailed response. Unfortunately I can't reproduce the error outside of our repo even by mimicking our repos and main app. I created a repo that reflects the structure of our Main App and the web component that has its own router here: https://github.com/sayyaari/TestRouter. A little more investigation of the error shows that when the url is changed Component-X won't be unmounted if it references the version Feliz.Router 3.10.0 but otherwise it will be unmounted. When it references the version 3.10.0 if the Url is changed in the main app the UrlChanged of Component-X Router will be triggered and if Component-X references Feliz.Router for example version 3.7.0 , the Component-X UrlChanged won't be trigged instead as expected it will be unmounted. Does it ring any bell for you?