Skip to content

React Tutorial Data and APIs

Rendering API Responses Safely in React

Lesson 95 of 156 2 min read By Deepak Paswan Updated Oct 10, 2026

Runnable lesson · press Try it on the examples to edit and run them here.

Real API data is messier than the examples in textbooks: fields are missing, names are awkward, dates are strings, lists are nested. This lesson shows how to turn a response into a safe, tidy screen.

Look at the data first

Before you write JSX, read a real response (use the Network tab of the browser’s developer tools, or the API docs). Note the shape: which fields are always there, which can be null or missing, and which are lists.

App.jsx
JSX
const response = {
  id: 7,
  title: "Mastering React",
  price_cents: 2999,
  published_at: "2026-03-15T09:30:00Z",
  author: { first_name: "Jane", last_name: "Doe" },
  cover_url: null,
  reviews: [
    { id: 1, rating: 5, text: "Great book" },
    { id: 2, rating: 4, text: null },
  ],
};

function App() {
  return (
    <article>
      <h2>{response.title}</h2>
      <p>By {response.author.first_name} {response.author.last_name}</p>
      <p>{response.reviews.length} reviews</p>
    </article>
  );
}

Shape the data once, near the edge

APIs use their own names and units (price_cents, first_name, ISO date strings). Convert the response into the shape your components want in one place (a small function), instead of scattering conversions through the JSX:

App.jsx
JSX
function toBook(api) {
  return {
    id: api.id,
    title: api.title,
    price: api.price_cents / 100,
    published: new Date(api.published_at),
    author: `${api.author.first_name} ${api.author.last_name}`,
    coverUrl: api.cover_url,                       // may be null
    reviews: api.reviews ?? [],
  };
}

const apiResponse = {
  id: 7,
  title: "Mastering React",
  price_cents: 2999,
  published_at: "2026-03-15T09:30:00Z",
  author: { first_name: "Jane", last_name: "Doe" },
  cover_url: null,
  reviews: [
    { id: 1, rating: 5, text: "Great book" },
    { id: 2, rating: 4, text: null },
  ],
};

const money = new Intl.NumberFormat("en-US", { style: "currency", currency: "USD" });
const dateFmt = new Intl.DateTimeFormat("en-GB", { dateStyle: "long", timeZone: "UTC" });

function Book({ book }) {
  return (
    <article>
      <h2>{book.title}</h2>
      <p>{book.author}</p>
      <p>{money.format(book.price)} - published {dateFmt.format(book.published)}</p>
      {book.coverUrl ? <img src={book.coverUrl} alt={`Cover of ${book.title}`} /> : <p>No cover image</p>}
      <ul>
        {book.reviews.map((r) => (
          <li key={r.id}>{"★".repeat(r.rating)} {r.text ?? "(no comment)"}</li>
        ))}
      </ul>
    </article>
  );
}

function App() {
  return <Book book={toBook(apiResponse)} />;
}

toBook is a plain function you can test without React. If the API changes a field name, you edit one place.

Defend against missing data

  • Optional chaining user?.address?.city returns undefined instead of crashing when something in the chain is missing. See Optional Chaining.
  • Nullish coalescing value ?? "fallback" replaces only null or undefined (Nullish Coalescing).
  • Defaults for lists: const items = data.items ?? [].
  • Check types at the boundary. A response is not guaranteed to match its documentation. For important data, validate it with a schema library or at least check the fields you rely on.
App.jsx
JSX
function App() {
  const user = { name: "Ada" };           // no address at all
  return <p>City: {user.address?.city ?? "unknown"}</p>;
}

The error you would see without the ?. is the famous “Cannot read properties of undefined”.

Dates, money and numbers

  • APIs send dates as ISO strings ("2026-03-15T09:30:00Z"); convert with new Date(...) and format with Intl.DateTimeFormat (Date formatting).
  • Money is often in cents to avoid floating-point errors; convert for display with Intl.NumberFormat.
  • IDs may be numbers or strings; keep them consistent when comparing.

Images from APIs

Always provide alt text, set width and height (or an aspect ratio) so the layout does not jump, and handle a missing URL with a placeholder. Use loading="lazy" for images far down the page.

Do not render untrusted HTML

If an API returns HTML (for example a rich-text description), React will show the tags as text. Avoid dangerouslySetInnerHTML. If you truly need it, sanitise the HTML with a library built for that, because API data can contain scripts. See API Security Fundamentals.

Keep keys stable

Use the API’s id as the list key, not the index (Understanding React Keys).

Key points

  • Inspect the real response, then convert it once into the shape your UI wants.
  • Use optional chaining, nullish coalescing and list defaults so missing data does not crash the page.
  • Format dates and money with Intl, and never inject API HTML without sanitising it.