NextJS 13中如何从JSON获取图片路径并引用public目录图片?
问题与解决方案
现有代码
1. getData.ts
export async function getData(){ const res = await fetch("http://localhost:3001/projects") return res.json() }
2. 接口返回的JSON格式
{ "projects": [{ "title": "Project 1", "description": "Description 1", "tags": ["example", "notReal", "placeholder", "lol", "rofl"], "imageURL": "project1IMG" },{ "title": "Project 2", "description": "Description 2", "tags": ["you", "get", "the", "idea"], "imageURL": "project2IMG" }] }
3. Projects组件(Test.tsx)
import React from "react" import { getData } from "@/lib/getdata" import Project from "./project" export default async function Test() { interface projectType{ title: string, description: string, tags: [], imageURL: string } const projects: projectType[] = await getData() return ( <section className="group"> <div> { projects.map((project, index) => ( <React.Fragment key={index}> <Project {...project} /> </React.Fragment> )) } </div> </section> ) }
4. Project组件
import Image from "next/image" type ProjectProps = typeof projectsData[0] export default function Project({ title, description, tags, imageURL, }: ProjectProps){ return ( <div> <h1>{title}</h1> <p>{description}</p> <ul> {tags.map((tag: string, index: number) => ( <li key={index}>{tag}</li> ))} </ul> <Image src={imageURL} alt="placeholder" width="100" height="100" /> </div> ) }
核心问题解决
一、引用@/public目录下的图片
Next.js中public目录下的资源可通过根相对路径直接访问,比如public/projects/project1IMG.jpg对应访问路径为/projects/project1IMG.jpg。按以下步骤调整:
- 统一图片存储路径:把所有项目图片放在
public的子目录中,比如public/projects/。 - 调整组件中Image的src属性:拼接基础路径与JSON返回的imageURL:
若图片直接放在<Image src={`/projects/${imageURL}`} // 若JSON中imageURL不带后缀,可拼接为`/projects/${imageURL}.jpg` alt={title} // 替换占位符为项目标题,提升可访问性 width={100} height={100} />public根目录,路径简化为/${imageURL}即可。
二、修正TypeScript类型声明
规范Projects组件中的类型定义:
明确tags为字符串数组,同时修正getData返回值的类型断言:// 改用大驼峰命名符合TS规范 interface ProjectType { title: string; description: string; tags: string[]; // 替换原空数组类型 imageURL: string; } // getData返回的是包含projects数组的对象,需调整类型匹配 const { projects }: { projects: ProjectType[] } = await getData();修正Project组件的Props类型:
复用定义好的ProjectType接口,避免依赖不存在的变量:import Image from "next/image"; // 可将类型单独抽离到@/types/project.ts中,方便多处引用 import type { ProjectType } from "./Test"; export default function Project({ title, description, tags, imageURL, }: ProjectType){ return ( <div> <h1>{title}</h1> <p>{description}</p> <ul> {tags.map((tag, index) => ( // TS会自动推导tag类型,无需额外声明 <li key={index}>{tag}</li> ))} </ul> <Image src={`/projects/${imageURL}`} alt={title} width={100} height={100} /> </div> ) }
额外优化建议
- 避免用index作为map的key,优先使用项目的唯一标识(若JSON中存在id字段)。
- 在getData中添加错误处理,防止请求失败导致页面崩溃:
export async function getData(){ const res = await fetch("http://localhost:3001/projects") if (!res.ok) { throw new Error('获取项目数据失败'); } return res.json() }
内容的提问来源于stack exchange,提问作者Scott James
相关产品推荐
相关产品推荐

