← All courses

Networking & Data Fetching

🗓 May 31, 2026 ⏱ 2 min read

Talking to a server

Most apps load data from a web API. JavaScript has a built-in fetch function, and many teams also use the popular axios library. Network requests are asynchronous — they take time — so you handle them without freezing the UI.

fetch with async/await

async function getUsers() {
  try {
    const response = await fetch('https://api.example.com/users');
    if (!response.ok) throw new Error('Server error ' + response.status);
    const data = await response.json();   // parse JSON
    return data;
  } catch (error) {
    console.error('Failed to load:', error);
    throw error;
  }
}

await pauses until the request finishes, but doesn’t block the app. Always wrap network calls in try/catch — networks fail.

Loading data in a screen (loading / error / success)

function UsersScreen() {
  const [users, setUsers] = useState([]);
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState(null);

  useEffect(() => {
    let active = true;
    (async () => {
      try {
        const data = await getUsers();
        if (active) setUsers(data);
      } catch (e) {
        if (active) setError('Could not load users');
      } finally {
        if (active) setLoading(false);
      }
    })();
    return () => { active = false; };
  }, []);

  if (loading) return <ActivityIndicator />;
  if (error) return <Text>{error}</Text>;
  return <FlatList data={users} keyExtractor={u => u.id}
            renderItem={({ item }) => <Text>{item.name}</Text>} />;
}

Always handle three states: loading (show a spinner), error (show a message + retry), and success (show the data). Skipping these leaves users staring at a blank screen.

Sending data (POST)

await fetch('https://api.example.com/users', {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({ name: 'Anand' }),
});

A note on data libraries

For real apps, libraries like React Query (TanStack Query) handle caching, retries, refetching and loading states for you — a big upgrade once you’re comfortable with the basics above.

Common mistakes

  • Not handling errors — always try/catch and show a message.
  • Forgetting to set loading back to false in a finally block.
  • Setting state after the screen has unmounted (use the active flag).
  • Forgetting the Content-Type header on POST requests.
Summary: Use fetch/axios with async/await inside useEffect, always handle loading, error and success states, and consider React Query for caching once you’ve mastered the fundamentals.