React中如何遍历API数组并根据nftId匹配展示数据
问题
React项目中,从API获取数组后,想用useParams拿到的nftId匹配数组中对应对象并展示信息,现有代码无法实现预期效果。
原代码
const {nftId} = useParams(); const [posts, setPost] = useState([]); console.log(nftId) async function fetchPost(nftId) { const {data} = await axios.get(`https://us-central1-nft-cloud-functions.cloudfunctions.net/hotCollections`) setPost(data) let lookup = {}; for (let i = 0; i < posts.length; i++) { if (posts.nftId === nftId) { lookup[posts[i].nftId] = posts[i] console.log(lookup) } } //data.filter(x => x.nftId === nftId).map(x=> console.log(x)) } useEffect(() => { fetchPost() }, [])
问题分析与修正
原代码存在的问题
- 调用
fetchPost时未传入nftId参数,导致函数内的nftId为undefined setPost(data)是异步操作,执行后posts不会立即更新,此时遍历posts仍是空数组- 循环判断逻辑错误:
posts.nftId应为posts[i].nftId,且手动构建lookup对象没必要,用数组方法更高效 useEffect依赖数组未包含nftId,当nftId变化时不会重新执行匹配逻辑
修正后的代码
import { useState, useEffect } from 'react'; import { useParams } from 'react-router-dom'; import axios from 'axios'; function NFTDetail() { const { nftId } = useParams(); const [posts, setPosts] = useState([]); // 单独存储匹配到的对象,方便页面渲染 const [matchedPost, setMatchedPost] = useState(null); async function fetchAndMatchPost() { try { const { data } = await axios.get('https://us-central1-nft-cloud-functions.cloudfunctions.net/hotCollections'); setPosts(data); // 直接用请求返回的data匹配,避开状态更新的异步性 const match = data.find(item => item.nftId === nftId); setMatchedPost(match); console.log('匹配到的NFT信息:', match); } catch (error) { console.error('API请求失败:', error); } } useEffect(() => { // 确保nftId存在时再执行匹配逻辑 if (nftId) { fetchAndMatchPost(); } }, [nftId]); // 依赖nftId,参数变化时自动重新匹配 return ( <div> {matchedPost ? ( <div className="nft-detail"> <h2>{matchedPost.name}</h2> <p>NFT ID: {matchedPost.nftId}</p> {/* 根据实际需求展示更多字段 */} </div> ) : ( <p>加载中...</p> )} </div> ); } export default NFTDetail;
关键优化点
- 直接用API返回的
data做匹配,避开React状态更新的异步特性 - 使用
find方法快速获取第一个匹配对象(若需多个匹配可改用filter) - 给
useEffect添加nftId依赖,确保参数变化时自动重新执行匹配 - 增加错误捕获,处理API请求失败的情况
- 单独维护
matchedPost状态,简化页面渲染逻辑
内容的提问来源于stack exchange,提问作者Rudis Gomez
相关产品推荐
相关产品推荐

