React中useEffect空依赖时页面刷新不重新fetch报错如何解决?
问题根源
你对空依赖useEffect的猜测是错误的:空依赖的useEffect会在每次组件挂载时都执行一次,页面刷新、热重载都会触发组件重新挂载,请求一定会重新发起。
报错的核心原因是:接口请求是异步的,useEffect里的fetch请求是在组件首次渲染完成后才触发的,首次渲染时你调用Object.keys(rates.rates)用的是rates的初始值,如果你给rates的初始值设为{}、null或undefined,此时rates.rates就是undefined,传入Object.keys就会抛出对应错误。你首次运行没报错只是偶发的缓存/渲染时序巧合,本质是初始值和渲染逻辑不匹配的必现问题。
解决方案
方案1:设置符合预期结构的初始值
给rates状态设置符合后续调用结构的初始值,从根源避免空值问题:
// 初始化时直接套对结构,保证rates.rates默认是空对象 const [rates, setRates] = useState({ rates: {} })
此时即使接口未返回,Object.keys(rates.rates)会拿到空数组,不会报错,只会暂时不渲染按钮。
方案2:添加条件渲染守卫
在调用Object.keys前先判断值是否存在,还可以顺便加加载提示:
return ( <div> {/* 只有rates.rates存在时才遍历,否则显示加载态 */} {rates?.rates ? Object.keys(rates.rates).map(code => <button key={code}>{code}</button>) : <span>加载汇率中...</span> } </div> )
可选简化写法:用可选链+空值合并直接兜底空对象:
Object.keys(rates?.rates ?? {})
补充说明
空依赖useEffect的配置本身没有问题,不需要修改,该配置可以保证同一个组件生命周期内只拉取一次数据,符合你的业务需求。
内容的提问来源于stack exchange,提问作者0Interest
相关产品推荐
相关产品推荐

