如何访问API并映射数据?API调用与数据渲染问题求助
问题分析与解决方案
核心问题拆解
- 状态处理错误:将API返回的数组转为字符串,导致无法使用
map遍历 - 初始状态缺失:未给
newsList设置初始空数组,首次渲染时undefined.map会报错 - 异步代码冗余:async函数混用
.then,写法不够简洁 - 错误边界缺失:未处理
newsList加载前的状态,可能引发渲染错误
修正后的代码
NewsList组件修正
import React from 'react'; import { useState, useEffect } from 'react' import { getNews } from '../../api/drupalAPI' export const NewsList = () => { // 初始状态设为空数组,避免首次渲染map报错 const [newsList, setNewsList] = useState([]); // 添加加载状态,优化用户体验 const [isLoading, setIsLoading] = useState(true); const [error, setError] = useState<string | null>(null); const fetchNewsList = async () => { try { // 用await替代.then,让异步逻辑更清晰 const response = await getNews(); // 直接存入数组,不要转成字符串 setNewsList(response); setError(null); } catch (err) { console.error('获取新闻列表失败:', err); setError('加载新闻失败,请稍后重试'); // 出错时重置列表为空数组 setNewsList([]); } finally { setIsLoading(false); } } useEffect(() => { fetchNewsList(); }, []); // 加载状态提示 if (isLoading) { return <div>加载中...</div>; } // 错误状态提示 if (error) { return <div>{error}</div>; } return ( <div> {newsList.length === 0 ? ( <div>暂无新闻</div> ) : ( newsList.map(news => ( // 必须给列表项加key,避免React警告 <div key={news.id}>{news.title}</div> )) )} </div> ); }
API层优化(可选)
import {News} from '@icofcv/common'; import store from '../store'; function getHeaders() { const headers: HeadersInit = { 'content-type': 'application/json;charset=UTF-8' }; const credentials = store.getState().session.credentials; // 简化条件判断,避免重复调用store.getState() if (credentials?.accessToken) { headers['Authorization'] = `Bearer ${credentials.accessToken}`; } return headers; } export async function getNews(): Promise<News[]> { const filter = { "offset": 0, "limit": 100, "skip": 0, "fields": { "id": true, "title": true, "creationDate": true, "enabled": true } }; try { const response = await fetch( `/news?filter=${encodeURIComponent(JSON.stringify(filter))}`, { method: "GET", headers: getHeaders() } ); if (!response.ok) { // 抛出更详细的错误信息,便于调试 throw new Error(`请求失败,状态码:${response.status}`); } const data = await response.json(); // 确保返回的数据是数组,避免类型错误 return Array.isArray(data) ? data : []; } catch (err) { console.error('API请求错误:', err); // 重新抛出错误,让上层组件处理 throw err; } }
关键修复说明
- 状态类型修正:移除
JSON.stringify(response),直接将API返回的数组存入状态,这样才能用map遍历对象并获取news.title属性。 - 初始状态设置:
useState([])确保首次渲染时newsList是数组,不会出现undefined.map的错误。 - 异步逻辑简化:用
await替代.then/.catch,让代码更易读,同时统一错误处理。 - 添加加载与错误状态:避免页面空白或报错,提升用户体验。
- 列表项key设置:React要求列表项必须有唯一
key,这里用news.id符合规范。 - API层健壮性优化:添加数组校验、简化header逻辑、抛出详细错误信息,便于调试API访问问题。
内容的提问来源于stack exchange,提问作者david Cuenca
相关产品推荐
相关产品推荐

