Search code examples
reactjsreact-routerreact-router-dom

unable to fetch data using Suspense and Await


I'm working on using Suspense and Await in my React app. I'm using data loaders to load the data before the component is rendered. When I simply use the loader function and the useLoderData function, I'm able to fetch the data. However, there is some delay in fetching the data so I want to defer the loader using Suspense and Await.

When I use this I only get some Response object. enter image description here

Home.jsx

import React, { Suspense } from "react";
import { getBookmarks } from "./api";
import { useLoaderData, defer, Await } from "react-router-dom";

export function loader() {
  return defer({ bookmarks: getBookmarks() });
}

export default function Home() {
  const dataPromise = useLoaderData();

  function renderBookMarks(bookmarks) {
    console.log(bookmarks);
  }

  return (
    <div>
      <h2>Welcome to bookmarks</h2>
       <Suspense fallback={<h2>Loading...</h2>}>
        <Await resolve={dataPromise.bookmarks}>
          {renderBookMarks}
        </Await>
      </Suspense>
    </div>
  )
}

api.js

import config from './config'

const apiUrl = config.apiUrl;
const apiPort = config.apiPort;

const joinUrl = (baseUrl, url) => {
  return ${baseUrl}/${url}
}

const domain = ${apiUrl}:${apiPort}/api/bookmarks;

export async function getBookmarks(url = "") {
  url = joinUrl(domain, url)
  const data = await fetch(url);
  return data;
}

Solution

  • You are returning the fetch response object, but you probably also want to unpack the response object, these days typically JSON.

    Example:

    export async function getBookmarks(url = "") {
      url = joinUrl(domain, url);
      const response = await fetch(url);
      const data = await response.json();
      return data;
    }