如何在React人物卡片中将SWAPI电影链接替换为电影标题?
解决SWAPI人物卡片中电影链接转标题的问题
嘿,我明白你的困扰——拿到的是一堆电影API链接,却不知道怎么把它们转换成观众看得懂的标题对吧?别担心,我们可以通过缓存电影数据+批量异步请求来搞定这个问题,还能避免重复调用API浪费资源。
步骤1:添加电影标题缓存的State
首先,我们需要一个地方来存储已经获取过的电影标题,用URL作为键,这样下次遇到同一个链接直接用缓存就行:
import { useState, useEffect } from 'react'; function PersonCard() { const [person, setPerson] = useState(null); const [filmTitles, setFilmTitles] = useState({}); // 缓存电影标题:{ [url]: title } // ... 后续代码 }
步骤2:写一个复用的电影标题获取函数
这个函数会先检查缓存,如果有直接返回;没有就发起请求,拿到标题后更新缓存:
const fetchFilmTitle = async (filmUrl) => { // 缓存命中,直接返回标题 if (filmTitles[filmUrl]) { return filmTitles[filmUrl]; } try { const response = await fetch(filmUrl); const filmData = await response.json(); // 更新缓存 setFilmTitles(prevState => ({ ...prevState, [filmUrl]: filmData.title })); return filmData.title; } catch (error) { console.error('获取电影标题失败:', error); return '无法加载电影'; } };
步骤3:在获取人物数据后批量加载电影标题
修改你原来的useEffect,在拿到人物数据后,批量请求所有电影链接的标题:
useEffect(() => { const fetchPersonData = async () => { try { // 先获取人物数据(这里替换成你的人物API请求) const personResponse = await fetch('https://swapi.dev/api/people/1/'); const personData = await personResponse.json(); // 批量请求所有电影标题,确保缓存更新完成 await Promise.all(personData.films.map(filmUrl => fetchFilmTitle(filmUrl))); // 把人物数据存入state setPerson(personData); } catch (error) { console.error('获取人物数据失败:', error); } }; fetchPersonData(); }, []);
步骤4:渲染电影标题
现在在人物卡片里,就可以直接从filmTitles中取出对应链接的标题了,还可以加个加载状态:
if (!person) { return <div>加载中...</div>; } return ( <div className="person-card"> <h2>{person.name}</h2> <p>出生日期: {person.birth_year}</p> <h3>参演电影:</h3> <ul> {person.films.map((filmUrl, index) => ( <li key={index}> {filmTitles[filmUrl] || '加载电影标题中...'} </li> ))} </ul> </div> );
额外优化点
- 如果你的页面有多个人物卡片,这个缓存机制会自动复用已经请求过的电影标题,不用重复调用API
- 可以用
useCallback包裹fetchFilmTitle函数,避免每次组件渲染都重新创建这个函数:
const fetchFilmTitle = useCallback(async (filmUrl) => { // 函数内容不变 }, [filmTitles]);
这样就能完美把电影链接转换成对应的标题展示啦!
内容的提问来源于stack exchange,提问作者Lukf
相关产品推荐
相关产品推荐

