Skip to content

Instantly share code, notes, and snippets.

@nicolasrenon
Created August 1, 2025 00:18
Show Gist options
  • Select an option

  • Save nicolasrenon/c25e15445aee9eaea08c92d9c6724b7a to your computer and use it in GitHub Desktop.

Select an option

Save nicolasrenon/c25e15445aee9eaea08c92d9c6724b7a to your computer and use it in GitHub Desktop.
Shared logic for Navbar Data
// components/DesktopNavigation.js
import useNavigationData from '../hooks/useNavigationData';
const DesktopNavigation = () => {
const { data: navLinks, loading, error } = useNavigationData();
if (loading) return <div>Loading...</div>;
if (error) return <div>Error: {error}</div>;
return (
<nav className="desktop-nav">
{navLinks?.map(link => (
<a key={link.id} href={link.url}>{link.title}</a>
))}
</nav>
);
};
export default DesktopNavigation;
// components/MobileNavigation.js
import useNavigationData from '../hooks/useNavigationData';
const MobileNavigation = () => {
const { data: navLinks, loading, error } = useNavigationData();
if (loading) return <div>Loading...</div>;
if (error) return <div>Error: {error}</div>;
return (
<div className="mobile-nav">
{navLinks?.map(link => (
<a key={link.id} href={link.url}>{link.title}</a>
))}
</div>
);
};
export default MobileNavigation;
// hooks/useNavigationData.js
import { useState, useEffect } from 'react';
let cachedData = null;
let isLoading = false;
let subscribers = new Set();
const useNavigationData = () => {
const [data, setData] = useState(cachedData);
const [loading, setLoading] = useState(isLoading && !cachedData);
const [error, setError] = useState(null);
useEffect(() => {
// Add this component to subscribers
subscribers.add(setData);
// If we already have cached data, return it
if (cachedData) {
setData(cachedData);
setLoading(false);
return;
}
// If already loading, just wait
if (isLoading) {
return;
}
// Start fetching
isLoading = true;
setLoading(true);
fetch('/api/navigation-links.json')
.then(response => {
if (!response.ok) {
throw new Error('Failed to fetch navigation data');
}
return response.json();
})
.then(result => {
cachedData = result;
isLoading = false;
// Update all subscribers
subscribers.forEach(subscriber => subscriber(result));
setLoading(false);
})
.catch(err => {
isLoading = false;
setError(err.message);
setLoading(false);
});
// Cleanup function
return () => {
subscribers.delete(setData);
};
}, []);
return { data, loading, error };
};
export default useNavigationData;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment