React函数组件使用Axios调用Rest API首次返回空数组问题求助
问题修复方案
核心问题点
- 接口返回的是单个事件对象,你给
eventDetails设置的初始值是空数组,两者类型不匹配,普通JS对象不存在length属性,你写的长度判断逻辑完全失效,才会出现展示异常。 - Axios是异步请求,组件首次渲染时请求还没返回结果,必然会先用初始值渲染,这是React的正常运行逻辑,不属于异常问题。
完整修复代码
import React, { useEffect, useState } from "react"; import { Card, Table } from "react-bootstrap"; import { FontAwesomeIcon } from '@fortawesome/react-fontawesome' import { faCoffee } from '@fortawesome/free-solid-svg-icons' import axios from "axios"; import { useParams } from "react-router-dom"; function EventsDetails () { // 修正初始值为null,增加loading状态避免渲染报错 const [eventDetails, setEventDetails] = useState(null) const [loading, setLoading] = useState(true) const { id } = useParams(); function getEvents() { setLoading(true) axios.get("http://localhost:8080/api/events/"+id) .then(response => response.data) .then((data) => { setEventDetails(data) }) .finally(() => { setLoading(false) }) } // 把id加入依赖数组,id变化时自动重新拉取数据 useEffect(()=>{ getEvents(); }, [id]) return ( <Card className={"border border-dark bg-dark text-white"}> <Card.Header><FontAwesomeIcon icon={faCoffee} /> 事件详情</Card.Header> <Card.Body> <Table bordered hover striped variant="dark"> <thead> <tr align="center"> <th>事件日期</th> <th>事件标题</th> <th>位置</th> <th>报名费用</th> <th>报名用户数</th> <th>操作</th> </tr> </thead> <tbody> {loading ? ( <tr align="center"> <td colSpan="6">数据加载中...</td> </tr> ) : !eventDetails ? ( <tr align="center"> <td colSpan="6">未查询到对应事件</td> </tr> ) : ( <tr align="center"> {/* 正确从事件对象取对应字段展示 */} <td>{new Date(eventDetails.eventDate).toLocaleString()}</td> <td>{eventDetails.title}</td> <td>-</td> <td>{eventDetails.eventFee}</td> <td>{eventDetails.playerSubscriptions?.length || 0}</td> <td>-</td> </tr> )} </tbody> </Table> </Card.Body> </Card> ) } export default EventsDetails
额外说明
- 用可选链操作符
?.读取嵌套属性,可以避免数据还没加载完成时报cannot read properties of null的错误 - 新增的loading状态可以更友好的提示用户数据加载状态,避免用户误以为页面无数据
内容的提问来源于stack exchange,提问作者JustM
相关产品推荐
相关产品推荐

