Uso next/image para cargar mis imágenes en mi aplicación. Funciona bien excepto por un carrusel con múltiples imágenes. Cuando me gusta esto tengo ese error:
Error: Falta la propiedad "src" requerida en la imagen. Asegúrese de pasar "src" en props al componente next/image . Recibió: {}
El problema no es porque tengo una entidad sin ningún archivo
imagen.js
import { getStrapiMedia } from "../utils/medias" import NextImage from "next/image" const Image = (props) => { if (!props.media) { return <NextImage {...props} /> } const { url, alternativeText } = props.media const loader = ({ src }) => { return getStrapiMedia(src) } return ( <NextImage loader={loader} layout="responsive" objectFit="contain" width={props.media.width} height={props.media.height} src={url} alt={alternativeText || ""} /> ) } export default ImageCarrusel.js
import React, { useCallback } from "react" import useEmblaCarousel from "embla-carousel-react" import NextImage from "./Image" export const EmblaCarousel = (product) => { const [emblaRef, emblaApi] = useEmblaCarousel() useEmblaCarousel.globalOptions = { loop: true } const scrollPrev = useCallback(() => { if (emblaApi) emblaApi.scrollPrev() }, [emblaApi]) const scrollNext = useCallback(() => { if (emblaApi) emblaApi.scrollNext() }, [emblaApi]) return ( <div className="embla" ref={emblaRef}> <div className="embla__container"> {product.gallery.map((_gallery) => ( <div key={_gallery.id}> <NextImage media={_gallery.image} className="embla__slide" /> </div> ))} </div> <button className="hidden md:inline embla__prev mr-2" onClick={scrollPrev} > Prev </button> <button className="hidden md:inline embla__next ml-2" onClick={scrollNext} > Next </button> </div> ) } export default EmblaCarouselel problema es
if (!props.media) { return <NextImage {...props} /> } en su componente de imagen personalizado. Cuando el accesorio de media es falso como undefined o null , está pasando todo lo demás a NextImage pero todo lo demás no incluye el accesorio src , que es obligatorio para el siguiente componente de imagen. Además, la extracción de su url depende de que la propiedad media sea veraz y tenga una propiedad llamada url . Se puede ver en la siguiente línea: -
const { url, alternativeText } = props.media
Y tiene la intención de pasar esta url a src como se puede ver en su uso. Puede devolver null cuando media son falsos o puede filtrar aquellos elementos en su lista donde media son falsos y luego mapearlos .
Reemplazar NextImage con Image
import { getStrapiMedia } from "../utils/medias" import Image from "next/image" const NextImage = (props) => { if (!props.media) { return <Image {...props} /> } const { url, alternativeText } = props.media const loader = ({ src }) => { return getStrapiMedia(src) } return ( <Image loader={loader} layout="responsive" objectFit="contain" width={props.media.width} height={props.media.height} src={url} alt={alternativeText || ""} /> ) } export default NextImageCarrusel.js
import React, { useCallback } from "react" import useEmblaCarousel from "embla-carousel-react" import NextImage from "./Image" export const EmblaCarousel = (product) => { const [emblaRef, emblaApi] = useEmblaCarousel() useEmblaCarousel.globalOptions = { loop: true } const scrollPrev = useCallback(() => { if (emblaApi) emblaApi.scrollPrev() }, [emblaApi]) const scrollNext = useCallback(() => { if (emblaApi) emblaApi.scrollNext() }, [emblaApi]) return ( <div className="embla" ref={emblaRef}> <div className="embla__container"> {product.gallery.map((_gallery) => ( <div key={_gallery.id}> <NextImage media={_gallery.image} className="embla__slide" /> </div> ))} </div> <button className="hidden md:inline embla__prev mr-2" onClick={scrollPrev} > Prev </button> <button className="hidden md:inline embla__next ml-2" onClick={scrollNext} > Next </button> </div> ) } export default EmblaCarousel