React中API获取数据后data.map()失效的问题排查与解决
React中data.map()无法生效的问题解决
问题核心
调用API后尝试用data.map()渲染数据,无论用data?.map()还是data && data.map()都无效,本质原因有两个:
- 请求的接口
https://jsonplaceholder.typicode.com/posts/1返回的是单个对象,而map()是数组专属方法,对象无法调用该方法 - 初始状态设置为
{data: []},后续setData(result)将单个对象赋值给data,此时data是对象类型,自然不存在map方法
解决方案
根据需求,有两种处理方式:
方式1:获取列表数据(使用返回数组的接口)
如果需要渲染多条数据,更换为返回数组的接口,同时修正初始状态为数组:
import { useState } from 'react'; const App = () => { // 初始状态改为空数组 const [data, setData] = useState([]); const [isLoading, setIsLoading] = useState(false); const [err, setErr] = useState(''); const handleClick = async () => { setIsLoading(true); try { // 更换为返回数组的接口 const response = await fetch('https://jsonplaceholder.typicode.com/posts', { method: 'GET', headers: { Accept: 'application/json', }, }); if (!response.ok) { throw new Error(`Error! status: ${response.status}`); } const result = await response.json(); setData(result); } catch (err) { setErr(err.message); } finally { setIsLoading(false); } }; return ( <div> {err && <h2>{err}</h2>} <button onClick={handleClick}>Fetch data</button> {isLoading && <h2>Loading...</h2>} {/* 现在data是数组,可以正常使用map */} {data.map((post) => ( <div key={post.id}> <h2>{post.title}</h2> <p>User ID: {post.userId}</p> <br /> </div> ))} </div> ); }; export default App;
方式2:渲染单个对象数据
如果只需要获取单条数据,直接渲染对象属性即可,无需使用map:
import { useState } from 'react'; const App = () => { // 初始状态改为空对象或null const [data, setData] = useState(null); const [isLoading, setIsLoading] = useState(false); const [err, setErr] = useState(''); const handleClick = async () => { setIsLoading(true); try { const response = await fetch('https://jsonplaceholder.typicode.com/posts/1', { method: 'GET', headers: { Accept: 'application/json', }, }); if (!response.ok) { throw new Error(`Error! status: ${response.status}`); } const result = await response.json(); setData(result); } catch (err) { setErr(err.message); } finally { setIsLoading(false); } }; return ( <div> {err && <h2>{err}</h2>} <button onClick={handleClick}>Fetch data</button> {isLoading && <h2>Loading...</h2>} {/* 判断data存在后直接渲染属性 */} {data && ( <div> <h2>{data.title}</h2> <p>User ID: {data.userId}</p> </div> )} </div> ); }; export default App;
额外注意点
- 初始状态的类型要和后续赋值的数据类型保持一致,避免类型混乱
- 原代码中
finally的括号书写错误,已在修正代码中修复
内容的提问来源于stack exchange,提问作者Swati
相关产品推荐
相关产品推荐

