State & Core HooksCore· 45 min read

Fetching Data in React

The full-stack moment: fetch live data from an API and render it — the exact React-to-server connection in MERN.

What you will learn

  • Fetch data in useEffect
  • Store results in state
  • Handle loading and error states

First, what are we doing?

So far our data lived inside the component. Real apps usually get their data from an API (Application Programming Interface — a way for two programs to talk to each other; here, a web address your code can ask for data). Your React app sends a request (a polite “please give me the users”) over the internet, and the API sends back a response (the data). The built-in fetch function is what makes that request from JavaScript.

The data usually comes back as JSON (JavaScript Object Notation — a simple text format for objects and arrays, e.g. [{ "name": "Asha" }]). We turn that text into a real JavaScript array so React can show it.

The standard data-fetching pattern

Store the data, the loading flag and any error in state, fetch inside useEffect with [] (run once), then render based on the current state.

Fetch live data, then render it
function App() {
  const [users, setUsers] = useState([]);
  const [loading, setLoading] = useState(true);

  useEffect(() => {
    fetch("https://jsonplaceholder.typicode.com/users")
      .then(res => res.json())
      .then(data => { setUsers(data); setLoading(false); });
  }, []);

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

  return (
    <ul>
      {users.map(u => (
        <li key={u.id}><b>{u.name}</b> — {u.email}</li>
      ))}
    </ul>
  );
}
Live preview

This combines everything: useState, useEffect and fetch. Here is the request-and-render flow in order:

  1. Set up state: users (the data, starts as an empty array) and loading (starts true because we have not loaded yet).
  2. Fetch on load: useEffect(() => { ... }, []) runs once after the first render and sends a request with fetch(url) to the API.
  3. Read the response: .then(res => res.json()) turns the raw response into a usable JavaScript array.
  4. Save it: .then(data => { setUsers(data); setLoading(false); }) stores the users in state and flips loading off. React re-renders.
  5. Render by state: while loading is true we return <p>Loading...</p>; once data has arrived we map over users to show each name and email.

Note: Output: For a split second you see Loading..., then a list of real people fetched from the internet, e.g.: • Leanne Graham — Sincere@april.biz • Ervin Howell — Shanna@melissa.tv …and so on.

Tip: The three states — loading, error, data — appear in every real app. Show a spinner while loading, a message on error, and the data when ready.

Note: In MERN, you will change this one URL to point at your own Node/Express API, which serves data from MongoDB. The React side stays exactly like this.

Q. Where should you fetch data when a component first loads?

Answer: Fetch inside useEffect with [] so it runs once after the first render, then store results in state to display them.

✍️ Practice

  1. Fetch users from the JSONPlaceholder API and render their names.
  2. Add a “Loading…” state and an error message.

🏠 Homework

  1. Fetch posts from an API and render them as styled cards with a loading state.
Want to learn this with a mentor?

CodingClave runs guided, project-based training (28-day, 45-day & 6-month batches).

Explore Training →