如何在Gallery组件内通过getStaticProps正确映射图片列表?
问题:Gallery组件内放置getStaticProps导致图片列表映射报错
原本在页面组件中通过props向Gallery组件传递图片列表时,映射功能正常。但将getStaticProps代码移到Gallery组件内部后,出现报错无法正常渲染图片列表。以下是当前的Gallery组件代码:
import galleryStyles from "../styles/Gallery.module.css"; import { Grid, IconButton } from "@mui/material"; import NavigateNextIcon from "@mui/icons-material/NavigateNext"; import NavigateBeforeIcon from "@mui/icons-material/NavigateBefore"; const Gallery = ({ images }) => { return ( <> <Grid className={galleryStyles.container}> <div className={galleryStyles.carousel}> <IconButton className={galleryStyles.previous}> <NavigateBeforeIcon /> </IconButton> <IconButton className={galleryStyles.next}> <NavigateNextIcon /> </IconButton> <ul> {images.map((image) => ( <li> <img key={image.id} src={image.url} /> </li> ))} </ul> </div> </Grid> </> ); }; export default Gallery; export const getStaticProps = async () => { const res = await fetch( "https://jsonplaceholder.typicode.com/photos?_limit=10" ); const images = await res.json(); return { props: { images, }, }; };
原因分析
Next.js的getStaticProps是页面专属的静态数据获取方法,仅能在pages目录下的页面组件中生效,普通组件无法识别该方法。因此你的Gallery组件接收不到images props,调用images.map()时会因images为undefined抛出错误。
解决方案
方案1:将getStaticProps移回页面组件(推荐,保留静态生成特性)
把getStaticProps放在pages目录下的页面文件中,通过props将图片数据传递给Gallery组件。
示例页面代码(如pages/gallery.js):
import Gallery from '../components/Gallery'; export default function GalleryPage({ images }) { return <Gallery images={images} />; } export const getStaticProps = async () => { const res = await fetch("https://jsonplaceholder.typicode.com/photos?_limit=10"); const images = await res.json(); return { props: { images }, }; };
Gallery组件保持原有代码,仅移除内部的getStaticProps即可。
方案2:在Gallery组件内部实现客户端数据获取
如果需要在组件内处理数据获取,可以使用useEffect结合useState实现客户端渲染,同时处理数据加载前的状态避免报错:
修改后的Gallery组件代码:
import { useState, useEffect } from 'react'; import galleryStyles from "../styles/Gallery.module.css"; import { Grid, IconButton } from "@mui/material"; import NavigateNextIcon from "@mui/icons-material/NavigateNext"; import NavigateBeforeIcon from "@mui/icons-material/NavigateBefore"; const Gallery = () => { const [images, setImages] = useState([]); const [loading, setLoading] = useState(true); useEffect(() => { const fetchImages = async () => { const res = await fetch("https://jsonplaceholder.typicode.com/photos?_limit=10"); const data = await res.json(); setImages(data); setLoading(false); }; fetchImages(); }, []); if (loading) { return <div>加载中...</div>; } return ( <> <Grid className={galleryStyles.container}> <div className={galleryStyles.carousel}> <IconButton className={galleryStyles.previous}> <NavigateBeforeIcon /> </IconButton> <IconButton className={galleryStyles.next}> <NavigateNextIcon /> </IconButton> <ul> {images.map((image) => ( <li key={image.id}> <img src={image.url} alt={`Gallery image ${image.id}`} /> </li> ))} </ul> </div> </Grid> </> ); }; export default Gallery;
注:这里把key移到了循环的根元素<li>上(符合React最佳实践),同时给图片添加了alt属性提升 accessibility。
内容的提问来源于stack exchange,提问作者lams
相关产品推荐
相关产品推荐

