You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React应用刷新页面后渲染接口数据时应用崩溃怎么办

问题背景
  • 开发项目为带主题切换功能的REST Countries API前端练习项目
  • 路由实现基于react-router-dom:点击国家列表项后跳转至/countryName路径匹配的国家详情页
  • 详情页数据获取逻辑:通过useLocation钩子读取当前URL,拆分路径得到国家名称参数,再通过axios请求接口获取对应国家的详情数据
  • 故障表现:从列表页首次进入详情页功能正常,在详情页执行刷新操作后应用直接崩溃无法渲染,代码中console.log(country[0].name.common)语句在刷新后返回undefined,触发运行时错误

故障代码如下:

import axios from 'axios'
import React,{ useEffect,useState } from 'react'
import { useNavigate, useLocation } from 'react-router-dom'

const Country = () => {
  const location = useLocation()
  const name = location.pathname.split('/')[1]
  const navigate = useNavigate()
  const [country,setCountry] = useState({})

  useEffect(() => {
    const getCountry = async() => {
      try {
        const res = await axios.get(`https://restcountries.com/v3.1/name/${name.toLowerCase()}?fullText=true`)
        console.log(res.data,res)
        setCountry(res.data)
      } catch (error) {
        console.log(error)
      }
    }
    getCountry()
  }, [name])

  console.log(country[0].name.common) // 刷新后返回undefined

  const backButton = (event) => {
    event.preventDefault()
    navigate('/')
  }

  return (
    <div className='country-page page'>
      <button onClick={backButton} className='backButton'>back button</button>
      <div className='country-page-layout'>
        <h2></h2>
      </div>
    </div>

  )
}

export default Country
故障原因
  1. 状态初始值类型不匹配:REST Countries API的name接口返回值为数组类型,但代码中country状态的初始值设置为空对象{}。组件首次渲染时,useEffect内的异步请求尚未返回结果,country仍为初始空对象,此时访问country[0]得到undefined,继续读取.name.common属性会直接触发类型错误,导致页面崩溃。
  2. 刷新触发全量重挂载:从列表页跳转进入详情页时无报错,是因为跳转过程的状态更新时序恰好避开了首次渲染的空值访问;刷新页面时前端内存存储的所有状态会被清空,组件完全按照初始值重新挂载渲染,必然触发空值访问错误。
修复方法
  • 将country状态的初始值修改为空数组[],与接口返回的数据类型保持一致
  • 增加加载状态与数据存在性校验:数据请求完成前,不直接访问数组项的嵌套属性,可通过可选链?.做安全访问,或渲染加载占位内容,避免读取不存在的属性
  • 关键修复代码示例:
// 修正初始值类型,新增加载状态
const [country,setCountry] = useState([])
const [loading, setLoading] = useState(true)

useEffect(() => {
  const getCountry = async() => {
    setLoading(true)
    try {
      const res = await axios.get(`https://restcountries.com/v3.1/name/${name.toLowerCase()}?fullText=true`)
      setCountry(res.data)
    } catch (error) {
      console.log(error)
    } finally {
      setLoading(false)
    }
  }
  getCountry()
}, [name])

// 加载状态渲染占位,属性访问增加可选链防护
if (loading) return <div className="page">加载中...</div>
console.log(country[0]?.name?.common)
参考材料
  • 错误信息截图:运行错误截图
  • 项目使用接口为REST Countries API

内容的提问来源于stack exchange,提问作者thefarerevenant

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.26 15:54:31