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.