Skip to main content

Overview

The useProtocolData hook provides a React-friendly interface to fetch and auto-refresh DeFi protocol data from DefiLlama. It handles loading states, error management, and automatic updates every 5 minutes. Location: src/hooks/useProtocolData.js

Import

import { useProtocolData } from '../hooks/useProtocolData';

Signature

function useProtocolData(): {
  protocols: Array<ProtocolData>;
  loading: boolean;
  error: string | null;
  lastUpdated: Date | null;
}

Return Values

protocols
Array<ProtocolData>
required
Array of protocol data objects with live TVL and APY
loading
boolean
required
true during initial data fetch, false once complete
error
string | null
required
Error message if fetch failed, otherwise null
lastUpdated
Date | null
required
Timestamp of last successful data refresh, null before first load

Usage Examples

import { useProtocolData } from '../hooks/useProtocolData';

function ProtocolDashboard() {
  const { protocols, loading, error, lastUpdated } = useProtocolData();

  if (loading) return <div>Loading protocols...</div>;
  if (error) return <div>Error: {error}</div>;

  return (
    <div>
      <p>Last updated: {lastUpdated?.toLocaleTimeString()}</p>
      
      {protocols.map(protocol => (
        <div key={protocol.id}>
          <h3>{protocol.name}</h3>
          <p>TVL: {protocol.tvl}</p>
          <p>APY: {protocol.apyDisplay}</p>
        </div>
      ))}
    </div>
  );
}

Features

Auto-Refresh

Automatically refetches data every 5 minutes to keep protocol data current

Static Fallback

Starts with static PROTOCOL_META data for instant UI rendering

Error Handling

Captures and exposes fetch errors without breaking the UI

Cleanup Safe

Cancels pending updates when component unmounts to prevent memory leaks

Behavior

Initial Load

  1. Hook starts with static protocol metadata from PROTOCOL_META
  2. loading is true
  3. Immediately fetches live data from DefiLlama
  4. Updates protocols with enriched data
  5. Sets loading to false and lastUpdated to current time

Auto-Refresh

  • Sets up 5-minute interval timer on mount
  • Silently refetches data in background
  • Updates protocols and lastUpdated on success
  • Does not show loading spinner during refresh (UX optimization)

Cleanup

return () => { 
  cancelled = true; 
  clearInterval(interval); 
};
Prevents state updates if component unmounts during fetch.

Implementation Details

Source Code

import { useState, useEffect } from 'react';
import { fetchAllProtocolData, PROTOCOL_META } from '../services/defiLlamaService';

export function useProtocolData() {
    const [protocols, setProtocols] = useState(PROTOCOL_META);
    const [loading, setLoading] = useState(true);
    const [error, setError] = useState(null);
    const [lastUpdated, setLastUpdated] = useState(null);

    useEffect(() => {
        let cancelled = false;
        async function load() {
            try {
                setLoading(true);
                const data = await fetchAllProtocolData();
                if (!cancelled) {
                    setProtocols(data);
                    setLastUpdated(new Date());
                }
            } catch (err) {
                if (!cancelled) setError(err.message);
            } finally {
                if (!cancelled) setLoading(false);
            }
        }
        load();
        // Refresh every 5 minutes
        const interval = setInterval(load, 5 * 60 * 1000);
        return () => { cancelled = true; clearInterval(interval); };
    }, []);

    return { protocols, loading, error, lastUpdated };
}

Performance

Initial Render: Instant with static data
First Load: ~1-2s for parallel API calls
Refresh Interval: 5 minutes (300,000ms)
Memory: Cleaned up on unmount

Comparison with Service

FeatureuseProtocolData HookfetchAllProtocolData Service
UsageReact componentsAny JavaScript context
State ManagementBuilt-in with useStateManual
Auto-RefreshYes (5 min interval)No
Error HandlingExposed as stateTry/catch required
Loading StateBuilt-inManual
CleanupAutomaticN/A

DefiLlama Service

Underlying service that fetches protocol data

useWalletProtocols Hook

Detect wallet positions in protocols

Build docs developers (and LLMs) love