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

createRootRoute does not render the pending component on initial page visit #2182

Open
SalzstangeSalamiBrief opened this issue Aug 23, 2024 · 2 comments

Comments

@SalzstangeSalamiBrief
Copy link

Describe the bug

Hello,

I want to load data that is relevant for the whole page (e.g. user related data) on the first load of the page and use it through the whole application where it is needed.
For that scenario, a loader function is added to the root of the application (__root.tsx).
Now the data is properly loaded and can be used through the whole application by using the function useLoaderData of the exported root component.
The problem is that while the loader is not resolved, an empty page is displayed.
Instead of an empty page, a loading spinner (or something else) should be displayed.
To achieve this behavior, a pendingComponent is added to the root.
The problem is that the component added as pendingComponent is not rendered so that the page is still empty while loading the page/data.

Your Example Website or App

https://stackblitz.com/edit/tanstack-router-4vc1d6?file=src%2Froutes%2F__root.tsx,src%2Fmain.tsx,src%2Froutes%2Findex.tsx&preset=node

Steps to Reproduce the Bug or Issue

Visit/reload the page

Expected behavior

Expected:
As a user, I expect that a pending component is shown while the loader is not resolved to ease the perceived loading time.

Current:
As a user I see an empty page without content so that I perceive the page as broken.

Screenshots or Videos

No response

Platform

  • OS: Windows
  • Browser: Chrome, Firefox, Firefox Developer Edition, Edge

Additional context

No response

@luansevero
Copy link

Need to set the wrapInSuspense option to true

import { Outlet, createRootRoute } from '@tanstack/react-router';

export const Route = createRootRoute({
  component: () => (
    <>
      <h1>Hello Root</h1>
      <Outlet />
    </>
  ),
  loader: () => new Promise((resolve) => setTimeout(resolve, 2000)),
  wrapISuspense: true,
  pendingComponent: () => <h2>pending</h2>,
});

@SalzstangeSalamiBrief
Copy link
Author

Thanks for you answer.
After setting the suggested flag the pendingComponent is properly displayed.
But now I am a bit confused:
As a substitute i used the defaultPendingComponent while initializing the router via createRouter:

import React from 'react';
import ReactDOM from 'react-dom/client';
import { RouterProvider, createRouter } from '@tanstack/react-router';
import { routeTree } from './routeTree.gen';

// Set up a Router instance
const router = createRouter({
  routeTree,
  defaultPendingComponent: () => <h2>Main Pending</h2>
});

// Register things for typesafety
declare module '@tanstack/react-router' {
  interface Register {
    router: typeof router;
  }
}

const rootElement = document.getElementById('app')!;

if (!rootElement.innerHTML) {
  const root = ReactDOM.createRoot(rootElement);
  root.render(<RouterProvider router={router} />);
}

This renders the pending component while the loader in __root.tsx is not resolved without using wrapInSuspense flag.
Do you know why that is?

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