typescriptbeginner
Image Lazy Load Component
Lazy load images with a blur-up placeholder effect using Intersection Observer and CSS transitions.
typescriptPress ⌘/Ctrl + Shift + C to copy
import { useState, useRef, useEffect } from 'react';
export function LazyImage({
src,
alt,
className = '',
}: {
src: string;
alt: string;
className?: string;
}) {
const [loaded, setLoaded] = useState(false);
const [inView, setInView] = useState(false);
const imgRef = useRef<HTMLDivElement>(null);
useEffect(() => {
const node = imgRef.current;
if (!node) return;
const observer = new IntersectionObserver(
([entry]) => { if (entry.isIntersecting) { setInView(true); observer.disconnect(); } },
{ rootMargin: '200px' }
);
observer.observe(node);
return () => observer.disconnect();
}, []);
return (
<div ref={imgRef} className={className}>
{inView && (
<img
src={src}
alt={alt}
onLoad={() => setLoaded(true)}
style={{
opacity: loaded ? 1 : 0,
transition: 'opacity 0.3s ease-in',
}}
/>
)}
</div>
);
}Use Cases
- Image galleries
- Blog post images
- E-commerce product grids
Tags
Related Snippets
Similar patterns you can reuse in the same workflow.
typescriptbeginner
Next.js Image Optimization Patterns
Use next/image with responsive sizes, blur placeholders, and priority loading for optimal Core Web Vitals.
Best for: Hero images
#images#optimization
typescriptbeginner
useDebounce — Debounced Value Hook
Debounce any rapidly-changing value with a configurable delay. Useful for search inputs and resize handlers.
Best for: Search-as-you-type
#hooks#debounce
typescriptintermediate
Portal-Based Modal Component
Accessible modal component using React portals with focus trapping, Escape key close, and backdrop click.
Best for: Confirmation dialogs
#modal#portal
typescriptintermediate
Infinite Scroll with Intersection Observer
Load more items as the user scrolls using IntersectionObserver. No external libraries required.
Best for: Feed pagination
#infinite-scroll#intersection-observer