最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

reactjs - react-router-dom loader use : If the fetch of the data is slow, how can we display a LoadingIndicator component - Stac

programmeradmin1浏览0评论

I'm using [email protected] and [email protected]

I have a simple Message Posting demo application to try react-router-dom features, and I couldn't figure how to handle a certain case:

This is my main.jsx:

import React from "react";
import ReactDOM from "react-dom/client";
import { RouterProvider, createBrowserRouter } from "react-router-dom";
import Posts, { loader as postsLoader } from "./routes/Posts";
import NewPost, { action as newPostAction } from "./routes/NewPost";
import RootLayout from "./routes/RootLayout";
import "./index.css";

const router = createBrowserRouter([
  {
    path: "/",
    element: <RootLayout />,
    children: [
      {
        path: "/",
        element: <Posts />,
        loader: postsLoader,
        children: [
          { path: "create-post", element: <NewPost />, action: newPostAction },
        ],
      },
    ],
  },
]);

const rootElement = document.getElementById("root");

ReactDOM.createRoot(rootElement).render(
  <React.StrictMode>
    <RouterProvider router={router} />
  </React.StrictMode>
);

I'm using [email protected] and [email protected]

I have a simple Message Posting demo application to try react-router-dom features, and I couldn't figure how to handle a certain case:

This is my main.jsx:

import React from "react";
import ReactDOM from "react-dom/client";
import { RouterProvider, createBrowserRouter } from "react-router-dom";
import Posts, { loader as postsLoader } from "./routes/Posts";
import NewPost, { action as newPostAction } from "./routes/NewPost";
import RootLayout from "./routes/RootLayout";
import "./index.css";

const router = createBrowserRouter([
  {
    path: "/",
    element: <RootLayout />,
    children: [
      {
        path: "/",
        element: <Posts />,
        loader: postsLoader,
        children: [
          { path: "create-post", element: <NewPost />, action: newPostAction },
        ],
      },
    ],
  },
]);

const rootElement = document.getElementById("root");

ReactDOM.createRoot(rootElement).render(
  <React.StrictMode>
    <RouterProvider router={router} />
  </React.StrictMode>
);

As you see, I'm using a loader function to load the posts to be used with Posts component. Here is Posts.jsx for reference:

import PostsList from "../components/PostsList";
import { Outlet } from "react-router-dom";

function Posts() {
  return (
    <>
      <Outlet />
      <main>
        <PostsList />
      </main>
    </>
  );
}

export default Posts;

export async function loader() {
  const response = await fetch("http://localhost:8080/posts");
  const data = await response.json();
  return data.posts;
}

And the simple RootLayout.jsx:

import { Outlet } from "react-router-dom";
import MainHeader from "../components/MainHeader";

function RootLayout() {
  return (
    <>
      <MainHeader />
      <Outlet />
    </>
  );
}

export default RootLayout;

And finally, my PostsList.jsx where I use useLoaderData to use that data in rendering posts.

import css from "./PostsList.module.css";
import Post from "./Post";
import { useLoaderData } from "react-router-dom";

function PostsList() {
  const posts = useLoaderData();

  return posts.length === 0 ? (
    <div className={css.noPosts}>
      <p>No posts found.</p>
    </div>
  ) : (
    <ul className={css.posts}>
      {posts.map((post) => (
        <Post
          key={post.id}
          enteredAuthor={post.author}
          enteredBody={post.body}
        />
      ))}
    </ul>
  );
}

export default PostsList;

The thing is, if I have a slow responding server, I'll have nothing to be displayed on screen. Even though the loader is attached to the Posts, it is the "/" route, thus RootLayout is not rendered as well, so I end up with an empty page (I tried this with adding some delay to the backend to return the response). How can I display a LoadingIndicator component when the data is still not available? Sorry if I couldn't explain my situation well enough. I am a new React learner and I would like to learn to use these new relatively new features well. Many thanks in advance.

Share Improve this question asked 2 days ago KorhanEKorhanE 212 bronze badges 1
  • I case you missed it, or haven't taken the full tour yet (you earn a badge BTW), there are 100% completely optional actions one can take after someone answers that helps rate and curate content on the site. – Drew Reese Commented 4 hours ago
Add a comment  | 

1 Answer 1

Reset to default 0

You could use the HydrateFallback or hydrateFallbackElement prop on the Route, but note this only works for the initial route page load.

{
  path: "/",
  element: <Posts />,
  loader: postsLoader,
  hydrateFallbackElement: <LoadingIndicator />,
  children: [
    { path: "create-post", element: <NewPost />, action: newPostAction },
  ],
},

An alternative would be to forego the route loader and implement the more conventional method of fetching data via a useEffect hook or using Redux-Toolkit Query or React-Query.

与本文相关的文章

发布评论

评论列表(0)

  1. 暂无评论