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

fix: AppRouter component #131

Merged
merged 12 commits into from
Jan 16, 2024
Merged

Conversation

patricklafrance
Copy link
Member

@patricklafrance patricklafrance commented Jan 16, 2024

Disclaimer

While fixing the AppRouter component it became clear that the current implementation is not good enough and that the whole AppRouter component should be refactored into something else.

However, as we must ship the platform, it's not the time to do so. Therefore, the current PR fix the ongoing issues and a refactor will be done at a later time.

Changes

AppRouter (BREAKING CHANGES)

  • The AppRouter component now requires to define a RouterProvider as a child. This change has been made to provide more flexibility on the consumer side about the definition of the React Router router.

Before:

<AppRouter
    fallbackElement={...}
    errorElement={...}
    waitForMsw={...}
 />

Now:

<AppRouter
    fallbackElement={...}
    errorElement={...}
    waitForMsw={...}
>
    {(routes, providerProps) => (
        <RouterProvider router={createBrowserRouter(routes)} {...providerProps} />
    )}
</AppRouter>
  • When in development and using React strict mode, the public and protected handler can be called twice. This issue highlighted that the AppRouter component doesn't equipe correctly the handlers to dispose of previous HTTP requests if they are called multiple times because of re-renders. Therefore, the handlers now receives an AbortSignal that should be forwared to the HTTP client initiating the fetch request.
  • The fix also requires the consumer to provide new properties (isPublicDataLoaded and isProtectedDataLoaded) indicating whether or not the public and/or protected data has been loaded.
async function fetchPublicData(setFeatureFlags: (featureFlags: FeatureFlags) => void, signal: AbortSignal) {
    try {
        const response = await fetch("/api/feature-flags", {
            signal
        });
        
        if (response.ok) {
            const data = await response.json();

            setFeatureFlags(data);
        }
    } catch (error: unknown) {
        if (!signal.aborted) {
            throw error;
        }
    }
}

const [featureFlags, setFeatureFlags] = useState<FeatureFlags>();

const handleLoadPublicData = useCallback((signal: AbortSignal) => {
    return fetchPublicData(setFeatureFlags, signal);
}, []);

<AppRouter
    onLoadPublicData={handleLoadPublicData}
    isPublicDataLoaded={!!featureFlags}
    fallbackElement={...}
    errorElement={...}
    waitForMsw={...}
>
    {(routes, providerProps) => (
        <RouterProvider router={createBrowserRouter(routes)} {...providerProps} />
    )}
</AppRouter>
  • Fixed an issue where the deferred registrations could be completed before the protected data has been loaded.

useNavigationItems (BREAKING CHANGES)

  • To be consistent with the other API of Squide, the useNavigationItems hook now accept an object literal of options rather than an optional menuId argument.

Before:

const items = useNavigationItems("my-custom-menu");

Now:

const items = useNavigationItems({ menuId: "my-custom-menu" });

alexasselin008
alexasselin008 previously approved these changes Jan 16, 2024
@patricklafrance patricklafrance merged commit 7caa44b into main Jan 16, 2024
1 check passed
@patricklafrance patricklafrance deleted the refactor/app-router-react-router-api branch January 16, 2024 15:45
@github-actions github-actions bot mentioned this pull request Jan 16, 2024
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

Successfully merging this pull request may close these issues.

2 participants