Lesson 32 +10 XP

Project 4: Real-Time Analytics Dashboard

Project 4: Real-Time Analytics Dashboard

In this final project, you will build an advanced Real-Time Analytics Dashboard that combines useMemo, useCallback, useRef, and code-splitting with React.lazy to deliver high performance.

Project Specifications

Your application will:

  1. Simulate real-time metric streams using useEffect intervals.
  2. Memoize expensive data filtering and chart calculations using useMemo.
  3. Preserve chart control function references using useCallback.
  4. Code-split heavy visualization components using React.lazy and Suspense.
import React, { useState, useEffect, useMemo, useCallback, Suspense, useRef } from 'react';

// Lazy load heavy chart component
const HeavyAnalyticsChart = React.lazy(() => import('./HeavyAnalyticsChart'));

export default function AnalyticsDashboard() {
  const [metrics, setMetrics] = useState([
    { id: 1, name: "CPU Load", value: 45, timestamp: Date.now() },
    { id: 2, name: "Memory", value: 68, timestamp: Date.now() }
  ]);
  const [filterMin, setFilterMin] = useState(0);
  const renderCountRef = useRef(0);
  renderCountRef.current += 1;

  // Simulate incoming real-time metric updates
  useEffect(() => {
    const interval = setInterval(() => {
      setMetrics(prev => [
        ...prev.slice(-19), // Keep last 20 metrics
        { id: Date.now(), name: "CPU Load", value: Math.floor(Math.random() * 100), timestamp: Date.now() }
      ]);
    }, 3000);

    return () => clearInterval(interval);
  }, []);

  // Memoize expensive metric filtering
  const filteredMetrics = useMemo(() => {
    console.log("Filtering metrics above:", filterMin);
    return metrics.filter(m => m.value >= filterMin);
  }, [metrics, filterMin]);

  // Stable callback handler for child actions
  const handleResetFilters = useCallback(() => {
    setFilterMin(0);
  }, []);

  return (
    <div className="dashboard-container">
      <h2>Real-Time System Analytics</h2>
      <p>Component Render Count: {renderCountRef.current}</p>

      <div className="controls">
        <label>Filter Minimum Load: {filterMin}%</label>
        <input 
          type="range" 
          min="0" 
          max="90" 
          value={filterMin} 
          onChange={e => setFilterMin(Number(e.target.value))} 
        />
        <button onClick={handleResetFilters}>Reset Filter</button>
      </div>

      {/* Lazy loaded Heavy Chart wrapped in Suspense */}
      <Suspense fallback={<div className="chart-loader">Loading Heavy Chart...</div>}>
        <HeavyAnalyticsChart data={filteredMetrics} />
      </Suspense>
    </div>
  );
}

Summary & TL;DR

  • Combines Hooks (useState, useEffect, useMemo, useCallback, useRef) into a real-world architecture.
  • Uses React.lazy & Suspense for optimized bundle performance.
  • Uses useRef to track component render counts without causing re-render loops.