React中useEffect Fetch获取数据异常:数组长度3却仅显示Array[0]
React Fetch API 问题及解决方案
问题详情
开发React应用时,使用Fetch调用基于SQLite的API,出现以下异常:
- 控制台显示返回数据长度为3,但展开后仅能看到Array[0]条目,无法获取id为1的数据
- 移除
console.log后可正常展示所有品牌,现需实现获取id为1的数据
相关代码:
import React, { useState, useEffect } from "react"; export default () => { const [brands, setBrands] = useState(null); useEffect(() => { fetch("/api/brands") .then((response) => response.json()) .then((data) => console.log(data)) .then((data) => { setBrands(data); }); }, []); return ( <> {brands ? ( <> <h1>Brands</h1> <ul> {brands.map((brand) => ( <li key={brand.id}>{brand.name}</li> ))} </ul> </> ) : ( <div>Loading...</div> )} </> ); };
控制台显示:数组长度标注为3,但展开后仅显示Array[0]条目
解决方案
第一步:修复Fetch Promise链的bug
当前代码中,console.log(data)没有返回值,导致后续then接收的data为undefined,这是数据显示异常的根源。修改方式如下:
useEffect(() => { fetch("/api/brands") .then((response) => response.json()) .then((data) => { console.log(data); return data; // 必须返回数据,供下一个then使用 }) .then((data) => { setBrands(data); }); }, []); // 或者合并两个then,更简洁: useEffect(() => { fetch("/api/brands") .then((response) => response.json()) .then((data) => { console.log(data); setBrands(data); }); }, []);
第二步:获取id为1的数据
有两种实现方式,根据你的API设计选择:
方式1:从已获取的品牌数组中筛选
如果已经拿到所有品牌数据,直接在前端筛选id为1的条目:
import React, { useState, useEffect } from "react"; export default () => { const [brands, setBrands] = useState(null); useEffect(() => { fetch("/api/brands") .then((response) => response.json()) .then((data) => { console.log(data); setBrands(data); }); }, []); // 筛选id为1的品牌 const brandId1 = brands?.find(brand => brand.id === 1); return ( <> {brands ? ( <> <h1>所有品牌</h1> <ul> {brands.map((brand) => ( <li key={brand.id}>{brand.name}</li> ))} </ul> <h1>ID为1的品牌</h1> {brandId1 ? ( <div>{brandId1.name}</div> ) : ( <div>未找到ID为1的品牌</div> )} </> ) : ( <div>Loading...</div> )} </> ); };
方式2:直接请求单个品牌的API(推荐)
如果你的API支持按ID查询(比如/api/brands/1),直接请求该接口,减少不必要的数据传输:
import React, { useState, useEffect } from "react"; export default () => { const [targetBrand, setTargetBrand] = useState(null); useEffect(() => { // 请求id为1的品牌数据 fetch("/api/brands/1") .then((response) => response.json()) .then((data) => { console.log(data); setTargetBrand(data); }); }, []); return ( <> {targetBrand ? ( <div> <h1>ID为1的品牌</h1> <div>{targetBrand.name}</div> </div> ) : ( <div>Loading...</div> )} </> ); };
内容的提问来源于stack exchange,提问作者Sheldon C
相关产品推荐
相关产品推荐

