Your Web News in One Place

Help Webnuz

Referal links:

Sign up for GreenGeeks web hosting
December 27, 2022 08:37 pm GMT

React Router Data Fetching

Introduction

In the most recent versions of React Router we were given a set of very interesting primitives and many of them are related to data fetching.

In the past, we always made http requests after the component was mounted and dealt with the loading and error status depending on the result of that request. That is, we only had two aspects into account, what and how we were going to fetch it. Now, we can think about when we want to fetch the data and the approach we can do is at the route level.

Basically, as soon as the user navigates to a new route, data loading and rendering is done in parallel.

Assumed knowledge

The following would be helpful to have:

  • Basic knowledge of React
  • Basic knowledge of React Router

Getting Started

Project Setup

Run the following command in a terminal:

yarn create vite router-defer --template reactcd router-defer

Now we can install the necessary dependencies:

yarn add react-router-dom

Build the Components

The first step is to build the component that will contain the app's <Outlet />, still in this component we will create a function called randomIntFromInterval() that will generate a random number within an interval.

// @src/components/Layout.jsximport { useCallback } from "react";import { Link, Outlet, useNavigate } from "react-router-dom";const Layout = () => {  const navigate = useNavigate();  const randomIntFromInterval = useCallback((min, max) => {    return Math.floor(Math.random() * (max - min + 1) + min);  }, []);  const handlePostavigation = useCallback(() => {    navigate(`/post/${randomIntFromInterval(6, 12)}`);  }, [randomIntFromInterval]);  return (    <div>      <nav>        <Link to="/">Home</Link>        <button onClick={handlePostavigation}>Random Post</button>      </nav>      <Outlet />    </div>  );};export default Layout;

As you may have noticed, the handlePostavigation() function will be responsible for generating a random integer that will be used as a route parameter. This parameter will be defined later in the router setup.

Create the Api Client

In today's example, we are going to consume two API endpoints JSONPlaceholder to get a specific post and its comments.

// @src/api.jsexport const getPostById = async (postId) => {  const response = await fetch(    `https://jsonplaceholder.typicode.com/posts/${postId}`  );  return await response.json();};export const getCommentsByPostId = async (postId) => {  const response = await fetch(    `https://jsonplaceholder.typicode.com/posts/${postId}/comments`  );  return await response.json();};

Build the Pages

With the Layout of our application created, we can start working on the pages. The first will be Home.jsx:

// @src/pages/Home.jsxconst Home = () => {  return (    <div>      <h1>Home page</h1>    </div>  );};export default Home;

Now let's go to the most important page of this article, the one where we will use the loader to get the article and the respective comments from the loader.

But first of all let's reflect a little on what we really need, because with this approach, we can reduce the number of spinners in the app and we can enjoy the features of <Suspense>.

The most important content on the page would be the content of the post itself and the comments would be secondary, that is, we can fetch the post content in the loader, but then we use the defer function so that later we can fetch the comments.

Now comes the question, how could we later fetch the comments, the answer is quite simple, we can enjoy the benefits of the <Await> component that renders the deferred values and even handles errors automatically.

// @src/pages/RandomPost.jsximport { Suspense } from "react";import { defer, useLoaderData, Await } from "react-router-dom";import { getCommentsByPostId, getPostById } from "../api";export const postLoader = async ({ params }) => {  const postId = params.postId;  const post = await getPostById(postId);  const commentsPromise = getCommentsByPostId(postId);  return defer({ post, commentsPromise });};const RandomPost = () => {  const { post, commentsPromise } = useLoaderData();  return (    <section>      <h2>{post.title}</h2>      <p>{post.body}</p>      <Suspense fallback={<small>Loading Comments...</small>}>        <Await resolve={commentsPromise}>          {(comments) =>            comments.map((comment) => (              <span key={comment.id}>                <small>{comment.body}</small>                <br />              </span>            ))          }        </Await>      </Suspense>    </section>  );};export default RandomPost;

In the loader() arguments we have access to some properties and one of them is the params object that in this case we need the postId, as well as what is returned from loader() is easily consumed by the useLoaderData() hook.

Router Setup

With the components and pages created, all that remains is to register our routes and assign the RandomPost page loader to the route.

// @src/App.jsximport {  Route,  createBrowserRouter,  createRoutesFromElements,  RouterProvider,} from "react-router-dom";import Layout from "./components/Layout";import HomePage from "./pages/Home";import RandomPostPage, { postLoader } from "./pages/RandomPost";const router = createBrowserRouter(  createRoutesFromElements(    <Route element={<Layout />}>      <Route index element={<HomePage />} />      <Route        path="/post/:postId"        loader={postLoader}        element={<RandomPostPage />}      />    </Route>  ));export const App = () => {  return <RouterProvider router={router} />;};

Conclusion

As usual, I hope you enjoyed the article and that it helped you with an existing project or simply wanted to try it out.

If you found a mistake in the article, please let me know in the comments so I can correct it. Before finishing, if you want to access the source code of this article, I leave here the link to the github repository.


Original Link: https://dev.to/franciscomendes10866/react-router-data-fetching-2ikh

Share this article:    Share on Facebook
View Full Article

Dev To

An online community for sharing and discovering great ideas, having debates, and making friends

More About this Source Visit Dev To