React js Fetching Data Practice Questions with Solutions

Introduction

Fetching Data in React means requesting information from an API or other external source and displaying it inside a React application. Data can include users, products, posts, courses, or other resources. React commonly uses fetch() with useEffect() to request data and useState() to store it for rendering. In this chapter, we will practice fetching data, handling loading and errors, displaying results, and working with fetched data in practical React components. React js Fetching Data practice questions with solutions help to build concepts.

1. What is Fetching Data in React?

Fetching Data means requesting information from an external source, usually an API, and using that information in a React application.

For example:

fetch("https://example.com/api/users")

The API may return:

[
  {
    "id": 1,
    "name": "Rahul"
  },
  {
    "id": 2,
    "name": "Priya"
  }
]

React can store this data in state and display it on the page.

A common flow is:

API
 ↓
fetch()
 ↓
Response
 ↓
JSON Data
 ↓
React State
 ↓
UI


2. How do you fetch data using fetch() in React?

The browser provides the fetch() function for making HTTP requests.

Example:

fetch("https://example.com/api/users")
  .then((response) => response.json())
  .then((data) => {
    console.log(data);
  })
  .catch((error) => {
    console.error(error);
  });

Here:

response.json()

parses the JSON response.

The resulting data can then be stored in React state.


3. How do you fetch data using useEffect()?

When data needs to be fetched as part of a component’s synchronization with an external system, useEffect() can be used.

Example:

import { useEffect, useState } from "react";

function Users() {
  const [users, setUsers] = useState([]);

  useEffect(() => {
    fetch("https://example.com/api/users")
      .then((response) => {
        if (!response.ok) {
          throw new Error("Failed to fetch users");
        }

        return response.json();
      })
      .then((data) => {
        setUsers(data);
      })
      .catch((error) => {
        console.error(error);
      });
  }, []);

  return (
    <div>
      <h1>Users</h1>

      {users.map((user) => (
        <p key={user.id}>{user.name}</p>
      ))}
    </div>
  );
}

export default Users;

The API request runs from the effect, and the received data is stored using:

setUsers(data);


4. How do you display fetched data in React?

After fetching data, store it in state and use JSX to display it.

Example:

import { useEffect, useState } from "react";

function Products() {
  const [products, setProducts] = useState([]);

  useEffect(() => {
    fetch("https://example.com/api/products")
      .then((response) => response.json())
      .then((data) => {
        setProducts(data);
      });
  }, []);

  return (
    <div>
      <h1>Products</h1>

      {products.map((product) => (
        <div key={product.id}>
          <h3>{product.name}</h3>
          <p>₹{product.price}</p>
        </div>
      ))}
    </div>
  );
}

export default Products;

The API data is rendered using:

products.map(...)

A stable unique identifier from the data should generally be used as the React key.


5. How do you handle Loading State while Fetching Data?

API requests take time, so it is useful to show a loading message while waiting for the response.

Example:

import { useEffect, useState } from "react";

function Users() {
  const [users, setUsers] = useState([]);
  const [loading, setLoading] = useState(true);

  useEffect(() => {
    async function fetchUsers() {
      try {
        const response = await fetch(
          "https://example.com/api/users"
        );

        if (!response.ok) {
          throw new Error("Request failed");
        }

        const data = await response.json();

        setUsers(data);
      } finally {
        setLoading(false);
      }
    }

    fetchUsers();
  }, []);

  if (loading) {
    return <h2>Loading users...</h2>;
  }

  return (
    <div>
      {users.map((user) => (
        <p key={user.id}>{user.name}</p>
      ))}
    </div>
  );
}

export default Users;

Initially:

Loading users...

is displayed.

After the request finishes, the users are displayed.


6. How do you handle Errors while Fetching Data?

You can use try...catch and check response.ok to handle request errors.

Example:

import { useEffect, useState } from "react";

function Users() {
  const [users, setUsers] = useState([]);
  const [error, setError] = useState("");

  useEffect(() => {
    async function fetchUsers() {
      try {
        const response = await fetch(
          "https://example.com/api/users"
        );

        if (!response.ok) {
          throw new Error("Failed to fetch users");
        }

        const data = await response.json();

        setUsers(data);
      } catch (error) {
        setError(error.message);
      }
    }

    fetchUsers();
  }, []);

  if (error) {
    return <h2>Error: {error}</h2>;
  }

  return (
    <div>
      {users.map((user) => (
        <p key={user.id}>{user.name}</p>
      ))}
    </div>
  );
}

export default Users;

Checking response.ok is important because fetch() does not automatically reject its Promise for HTTP responses such as 404 or 500.


7. How do you fetch Data using async/await?

async/await provides another way to write asynchronous fetching code.

Example:

import { useEffect, useState } from "react";

function Products() {
  const [products, setProducts] = useState([]);

  useEffect(() => {
    async function fetchProducts() {
      const response = await fetch(
        "https://example.com/api/products"
      );

      if (!response.ok) {
        throw new Error("Failed to fetch products");
      }

      const data = await response.json();

      setProducts(data);
    }

    fetchProducts().catch((error) => {
      console.error(error);
    });
  }, []);

  return (
    <div>
      {products.map((product) => (
        <p key={product.id}>{product.name}</p>
      ))}
    </div>
  );
}

export default Products;

A common pattern is to define the asynchronous function inside the effect.

The effect callback itself should not normally be declared async, because React expects the effect callback to return either nothing or a cleanup function.


8. How do you fetch Data based on a Changing ID?

Sometimes the API request depends on a value such as a user ID.

Example:

import { useEffect, useState } from "react";

function User({ userId }) {
  const [user, setUser] = useState(null);

  useEffect(() => {
    async function fetchUser() {
      const response = await fetch(
        `https://example.com/api/users/${userId}`
      );

      if (!response.ok) {
        throw new Error("Failed to fetch user");
      }

      const data = await response.json();

      setUser(data);
    }

    fetchUser().catch((error) => {
      console.error(error);
    });
  }, [userId]);

  if (!user) {
    return <p>Loading user...</p>;
  }

  return <h2>{user.name}</h2>;
}

export default User;

The dependency array contains:

[userId]

When userId changes, the effect runs again and requests data for the new user.


9. How do you fetch Data and render a List?

You can fetch an array of data and use map() to display each item.

Example:

import { useEffect, useState } from "react";

function Posts() {
  const [posts, setPosts] = useState([]);

  useEffect(() => {
    async function fetchPosts() {
      const response = await fetch(
        "https://example.com/api/posts"
      );

      if (!response.ok) {
        throw new Error("Failed to fetch posts");
      }

      const data = await response.json();

      setPosts(data);
    }

    fetchPosts().catch((error) => {
      console.error(error);
    });
  }, []);

  return (
    <div>
      <h1>Latest Posts</h1>

      {posts.map((post) => (
        <article key={post.id}>
          <h2>{post.title}</h2>
          <p>{post.body}</p>
        </article>
      ))}
    </div>
  );
}

export default Posts;

The important part is:

posts.map((post) => (
  <article key={post.id}>
    <h2>{post.title}</h2>
    <p>{post.body}</p>
  </article>
))

This converts each API item into React UI.


10. How do you Build a Practical Data Fetching Component?

Let’s create a complete example with:

  • API fetching
  • Loading state
  • Error handling
  • Data rendering
  • Request cancellation
import { useEffect, useState } from "react";

function Products() {
  const [products, setProducts] = useState([]);
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState("");

  useEffect(() => {
    const controller = new AbortController();

    async function fetchProducts() {
      try {
        setLoading(true);
        setError("");

        const response = await fetch(
          "https://example.com/api/products",
          {
            signal: controller.signal
          }
        );

        if (!response.ok) {
          throw new Error("Failed to fetch products");
        }

        const data = await response.json();

        setProducts(data);
      } catch (error) {
        if (error.name !== "AbortError") {
          setError(error.message);
        }
      } finally {
        setLoading(false);
      }
    }

    fetchProducts();

    return () => {
      controller.abort();
    };
  }, []);

  if (loading) {
    return <h2>Loading products...</h2>;
  }

  if (error) {
    return <h2>Error: {error}</h2>;
  }

  return (
    <div>
      <h1>Product List</h1>

      {products.length === 0 ? (
        <p>No products found.</p>
      ) : (
        products.map((product) => (
          <div key={product.id}>
            <h3>{product.name}</h3>
            <p>Price: ₹{product.price}</p>
          </div>
        ))
      )}
    </div>
  );
}

export default Products;

How this example works

The component maintains three states:

const [products, setProducts] = useState([]);
const [loading, setLoading] = useState(true);
const [error, setError] = useState("");

They represent:

products → fetched API data
loading  → request status
error    → error message

The request is made inside useEffect().

If the request succeeds:

setProducts(data);

stores the received products.

If the request fails:

setError(error.message);

stores the error message.

The cleanup function:

return () => {
  controller.abort();
};

can cancel the request if the effect is cleaned up while the request is still in progress.

Finally, the component displays either:

Loading products...

or:

Error: ...

or the fetched product list.

This pattern provides a strong foundation for API-driven React applications.

Key Takeaways

  • Fetching Data means requesting information from an external source such as an API.
  • The browser’s fetch() function can be used to make HTTP requests.
  • useEffect() is commonly used when fetching data needs to synchronize a component with an external system.
  • useState() can store fetched data for rendering.
  • Always consider loading and error states.
  • Check response.ok before treating an HTTP response as successful.
  • async/await can make asynchronous code easier to understand.
  • Dependencies can control when an effect re-synchronizes with changing values.
  • map() can be used to render lists of fetched data.
  • AbortController can cancel an in-progress fetch request when appropriate.
  • Stable unique IDs from API data are generally preferred as React list keys.

FAQs

1. What is Data Fetching in React?

Data Fetching is the process of requesting data from an API or another external source and using that data in a React application.

2. Which function is commonly used to fetch data in React?

The browser’s built-in fetch() function is commonly used.

const response = await fetch("/api/users");

3. Why is useEffect commonly used for data fetching?

useEffect() is useful when a component needs to synchronize with an external system such as a network request.

4. How do you store fetched data in React?

You can store fetched data using useState().

const [users, setUsers] = useState([]);

Then update it after receiving the API response:

setUsers(data);

5. How do you show a loading message while fetching data?

Create a loading state:

const [loading, setLoading] = useState(true);

Then conditionally display:

if (loading) {
  return <p>Loading...</p>;
}

6. How do you handle errors while fetching data?

Use try...catch with async/await and check response.ok.

try {
  const response = await fetch("/api/users");

  if (!response.ok) {
    throw new Error("Failed to fetch users");
  }

  const data = await response.json();
} catch (error) {
  console.error(error);
}

7. Can fetched API data be displayed using map()?

Yes. If the API returns an array, map() can be used to create React elements.

users.map((user) => (
  <p key={user.id}>{user.name}</p>
))

A stable unique identifier should generally be used for the key.

Written by Shubhranshu Shekhar, who has trained 20000+ students in coding.

Scroll to Top