React中fetch获取的API数据无法在div中渲染的解决方法
问题根因
- 普通
let声明的response变量不是React响应式状态,赋值更新后不会触发组件重新渲染,页面自然拿不到更新后的值。 - 组件每次渲染时都会重新执行
let response = [],就算你之前给response赋过接口返回值,重渲染时也会被直接重置为空数组。 - 硬编码渲染
response[0]到response[3]的写法兼容性差,一旦接口返回的列表长度和预期不符,就会出现空白项或者内容缺失。
修正代码
核心改动是用useState存储接口返回的分类数据,数据更新后自动触发视图重渲染,同时通过数组map方法遍历生成列表项,避免硬编码下标。
import Head from "next/head"; import "../node_modules/bootstrap/dist/css/bootstrap.css"; import Nav from "./nav"; //import express from "../node_modules/express/index"; import categories from "./API1_getCategories"; import React, { useEffect, useState } from "react"; const App = () => { // 用响应式state存储分类列表,初始值为空数组 const [categoryList, setCategoryList] = useState([]); // 可选:加加载状态,避免用户点击后无反馈 const [loading, setLoading] = useState(false); const fetchCategories = () => { setLoading(true); fetch('https://fakestoreapi.com/products/categories') .then(res=>res.json()) .then(json=>{ console.log(json); // 通过state更新方法赋值,自动触发页面重渲染 setCategoryList(json); }) .finally(()=>{ setLoading(false); }) } return( <> <Head> <link rel="stylesheet" href="./css/general.css"></link> </Head> <div> <div className="searchbardiv"> <input type="text" placeholder="Search"></input> <a href="./jewellery"><img src="./images/cart.png" /></a> <a href="./electronics"><img src="./images/avatar.jpg" /></a> </div> <div className="categories"> <div> <button type="button" onClick={fetchCategories} disabled={loading} > {loading ? '加载中...' : 'Show categories'} </button> </div> {/* 遍历state中的数组自动渲染列表,不用硬编码下标 */} {categoryList.map((item, index) => ( <div key={index}>{item}</div> ))} </div> <div className="homepageproducts"> <div>prod1</div> <div>prod2</div> <div>prod3</div> <div>prod4</div> </div> </div> </> ) } export default App;
额外说明
- 原按钮的
type写的是submit,外层没有表单的话建议改成button,避免触发默认表单提交行为导致页面意外刷新。 - 遍历列表生成DOM时记得加唯一的
key属性,这里用数组下标做key仅适合列表内容不会动态增删排序的场景,如果后续分类有交互调整,建议用接口返回的唯一字段作为key值。 - 如果需要页面加载时就自动拉取分类数据,不用等用户点击按钮,可以把fetch逻辑放到
useEffect里执行,不用绑定点击事件。
内容的提问来源于stack exchange,提问作者Leo
相关产品推荐
相关产品推荐

