Этот вопрос касается стратегий обработки ошибок загрузки изображений в веб-приложениях.
Для обработки битых картинок используйте событие onError на элементе <img> чтобы заменить src на fallback изображение, установить состояние ошибки в React компоненте, или скрыть/заменить элемент. Также можно использовать CSS для показа плейсхолдера и предзагрузку критически важных изображений.
Обработка битых изображений важна для пользовательского опыта и надежности приложения.
Методы обработки:
1. Базовый JavaScript подход:
// Обработка на чистом JS
const img = new Image();
img.src = 'image.jpg';
img.onerror = function() {
this.src = '/fallback.jpg';
this.alt = 'Изображение не найдено';
};2. React компонент с обработкой ошибок:
const ImageWithFallback = ({ src, alt, fallback }) => {
const [error, setError] = useState(false);
const handleError = () => {
setError(true);
};
return (
<img
src={error ? fallback : src}
alt={alt}
onError={handleError}
/>
);
};
// Использование
<ImageWithFallback
src="/possible-broken-image.jpg"
fallback="/default-image.jpg"
alt="Описание"
/>3. Кастомный хук для изображений:
const useImageLoader = (src) => {
const [status, setStatus] = useState('loading');
useEffect(() => {
const img = new Image();
img.src = src;
img.onload = () => setStatus('loaded');
img.onerror = () => setStatus('error');
return () => {
img.onload = null;
img.onerror = null;
};
}, [src]);
return status;
};
// Использование в компоненте
const ImageComponent = ({ src }) => {
const status = useImageLoader(src);
if (status === 'loading') {
return <div className="image-placeholder">Загрузка...</div>;
}
if (status === 'error') {
return <img src="/fallback.jpg" alt="Запасное изображение" />;
}
return <img src={src} alt="Основное изображение" />;
};4. Множественные fallback'и:
const RobustImage = ({ src, alt, fallbacks = [] }) => {
const [currentIndex, setCurrentIndex] = useState(0);
const sources = [src, ...fallbacks];
const handleError = () => {
if (currentIndex < sources.length - 1) {
setCurrentIndex(currentIndex + 1);
}
};
return (
<img
src={sources[currentIndex]}
alt={alt}
onError={handleError}
/>
);
};
// Использование с несколькими запасными вариантами
<RobustImage
src="/primary-image.jpg"
fallbacks={[
'/secondary-image.jpg',
'/tertiary-image.png',
'/final-fallback.jpg'
]}
alt="Очень надежное изображение"
/>5. CSS-based подход:
.image-container {
position: relative;
width: 100%;
height: 200px;
background-color: #f0f0f0;
}
.image-container img {
width: 100%;
height: 100%;
object-fit: cover;
}
.image-container img:error {
display: none;
}
.image-container:has(img:error)::after {
content: 'Изображение не доступно';
display: flex;
align-items: center;
justify-content: center;
height: 100%;
color: #666;
}6. Предзагрузка и кэширование:
// Предзагрузка критических изображений
const preloadImages = (urls) => {
urls.forEach(url => {
const img = new Image();
img.src = url;
});
};
// Использование
useEffect(() => {
preloadImages([
'/critical-image1.jpg',
'/critical-image2.jpg',
'/fallback-image.jpg'
]);
}, []);Лучшие практики:
Всегда предоставляйте alt текст
Используйте lazy loading для не-critical изображений
Имейте multiple fallback стратегии
Мониторьте ошибки загрузки изображений