React TypeScript对接芝加哥艺术学院API展示艺术品数据
问题修复方案
你现有代码存在几个核心问题,直接导致接口数据无法正常展示:
- 接口请求逻辑写在组件外部,请求拿到的数据仅打印到控制台,没有绑定React组件状态,数据无法驱动视图渲染
- 芝加哥艺术学院API返回的
image_id字段不是可直接访问的完整图片URL,需要按照官方规则拼接图片服务地址才能正常加载 - 没有处理请求加载中、请求失败的边界场景
- 组件JSX结构里没有预留艺术品列表的渲染位置
- 请求地址里误用了HTML转义字符
&,在JS代码中需要用原生&连接参数,否则接口会解析错误
修复后完整代码
import { useState, useEffect } from 'react'; import { Navbar } from '../Navbar'; import Real from '../../assets/images/scream.jpeg' import { makeStyles } from '@material-ui/core'; const useStyles = makeStyles({ background: { backgroundImage: `linear-gradient(rgba(0,0,0,0.5) 0%, rgba(0,0,0,0.5) 50%, rgba(0,0,0,0.5) 100%), url(${Real})`, width: '100%', minHeight: '100vh', backgroundSize: "cover", backgroundRepeat: "no-repeat", backgroundPosition: "center", position: "absolute", zIndex: -1, }, main_text: { textAlign: 'center', position: 'relative', top: '30%', left: '50%', transform: 'translate(-50%, 0)', color: 'white', width: '90%', maxWidth: '1200px', paddingBottom: '60px' }, artList: { display: 'grid', gridTemplateColumns: 'repeat(auto-fill, minmax(280px, 1fr))', gap: '24px', marginTop: '32px' }, artCard: { background: 'rgba(255,255,255,0.1)', borderRadius: '8px', padding: '16px', backdropFilter: 'blur(4px)' }, artImage: { width: '100%', height: '320px', objectFit: 'cover', borderRadius: '4px', marginBottom: '12px' } }) async function getArt() { let response = await fetch(`https://api.artic.edu/api/v1/artworks?ids=208131,240935,142595,120300,13454,151363,102611,191556,117266,137125,126414&fields=id,title,image_id`); if(!response.ok) throw new Error('艺术品数据获取失败') let data = await response.json() return data.data; } export const Art = () => { const classes = useStyles(); const [artList, setArtList] = useState([]) const [loading, setLoading] = useState(true) const [error, setError] = useState('') useEffect(() => { getArt() .then(data => setArtList(data)) .catch(err => setError(err.message)) .finally(() => setLoading(false)) }, []) return ( <> <Navbar /> <div className={`${classes.background}`}> <div className={classes.main_text}> <h1>艺术学院藏品精选</h1> {loading && <p>藏品加载中...</p>} {error && <p>加载出错:{error}</p>} <div className={classes.artList}> {artList.map(art => ( <div key={art.id} className={classes.artCard}> <img className={classes.artImage} src={`https://www.artic.edu/iiif/2/${art.image_id}/full/843,/0/default.jpg`} alt={art.title} /> <p>{art.title}</p> </div> ))} </div> </div> </div> </> ) }
关键说明
- 图片拼接规则固定:
https://www.artic.edu/iiif/2/{image_id}/full/{宽度像素},/0/default.jpg,示例里用的843是常规展示宽度,需要高清图可以把数值改成1686,需要缩略图改成200即可 - 后续如果需要展示更多藏品信息,直接在接口请求的
fields参数里追加字段名即可,比如要展示作者名就把参数改成fields=id,title,image_id,artist_title,渲染时对应取值就行 - 把请求逻辑放到
useEffect里,且依赖数组为空,可以保证组件挂载时只请求一次数据,不会造成重复调用
内容的提问来源于stack exchange,提问作者Schadre
相关产品推荐
相关产品推荐

