Frontend Patterns

Pattern

Effect-Based Fetching

Trigger data fetches as side effects when components mount or dependencies change.

Effect-Based Fetching

Problem

Data fetching logic scattered throughout components makes it unclear when and how data loads. Components display empty or stale data when properties change because fetches don’t re-run. Users see outdated information after filter changes, navigation, or property updates. Developers struggle to coordinate when fetches should trigger and often miss edge cases.

Solution

Trigger data fetching as a side effect of component mounting or prop changes rather than in response to user actions. This automatically keeps data fresh as users navigate, though it can lead to waterfalls and race conditions.

Example

This example demonstrates fetching data automatically when a component attribute changes, keeping data fresh as the user-id updates.

// Web Component that fetches data when attributes change
class UserProfile extends HTMLElement {
  // Declare which attributes to observe for changes
  static get observedAttributes() {
    return ['user-id'];
  }

  // Called whenever an observed attribute changes
  attributeChangedCallback(name, oldValue, newValue) {
    // Only fetch if user-id actually changed to a new value
    if (name === 'user-id' && newValue !== oldValue) {
      this.fetchUser(newValue);
    }
  }

  async fetchUser(userId) {
    // Fetch user data based on the new user ID
    const response = await fetch(`/api/users/${userId}`);
    const user = await response.json();
    this.render(user);
  }

  render(user) {
    // Display the fetched user data
    this.innerHTML = `<div>${user?.name || ''}</div>`;
  }
}

customElements.define('user-profile', UserProfile);

Benefits

  • Automatically refetches data when dependencies like IDs or filters change.
  • Keeps displayed data synchronized with current component props.
  • Simple pattern that’s easy to understand and implement.
  • Works well for basic data fetching scenarios.
  • Integrates naturally with component lifecycle.

Tradeoffs

  • Can create request waterfalls with nested dependent components.
  • Race conditions occur when props change during pending requests.
  • Difficult to coordinate loading states across multiple effects.
  • May trigger unnecessary refetches on every prop change.
  • Requires careful cleanup to cancel stale requests.
Stay Updated

Get New Patterns
in Your Inbox

Join thousands of developers receiving weekly insights on frontend architecture patterns

No spam. Unsubscribe anytime.