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

页面刷新时React useEffect无法填充状态,致words.map报错

问题分析

页面刷新时触发words.map is not a function错误,核心原因是API返回的数据不是数组,导致setWords(data)把初始为空数组的words改成了非数组类型(比如错误对象、null或嵌套数组的对象)。

至于注释useEffect再恢复就正常的情况,大概率是刷新时token还未初始化完成,请求用了空token导致鉴权失败,API返回了错误内容;而后续手动恢复useEffect时,token已经就绪,请求成功返回了数组。

解决方案

1. 先排查API返回值

在case2的const data = await response.json();后面加控制台打印,刷新页面看真实返回:

const data = await response.json();
console.log('Case2返回数据:', data);
  • 如果返回的是嵌套数组的对象(比如{vocabList: [...]}),要改成setWords(data.vocabList)而非直接setWords(data);
  • 如果返回错误对象(比如{error: "Unauthorized"}),说明token在刷新时未就绪,请求未通过鉴权。

2. 给words加类型兜底

不管API返回什么,强制保证words始终是数组:

// case1和case2中统一修改
const data = await response.json();
setWords(Array.isArray(data) ? data : []);

3. 补全useEffect的依赖项

你的useEffect里用到了token和id,但依赖项只有wordText,这会导致:

  • 刷新时token未初始化就发起请求,返回错误;
  • id变化时不会重新触发请求。

补全依赖项:

useEffect(() => {
  // ... 原有请求逻辑
}, [wordText, token, id])

4. 渲染时加安全校验

在map之前先判断words是否为数组,避免报错,同时修正JSX的写法(不要用数组包裹元素,必须加唯一key):

return (
  <div>
    {Array.isArray(words) && words.map((word, index) => (
      <div key={word.id || index}>
        <h1 onClick={(e) => {
          setWordText(word.word_text); 
          handleClick(index); 
          translateWord(e)
        }}>
          {word.word_text}
        </h1>
      </div>
    ))} 
  </div>
)

注:优先用word.id作为key,index是兜底方案,避免React渲染警告。

5. 处理token加载状态

如果token是异步获取的(比如从localStorage读取),要确保token存在再发起请求:

const getWordsBlock = async () => {
  if (!token) return; // token未就绪时不发起请求
  // ... 原有请求代码
}

内容的提问来源于stack exchange,提问作者M.good

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.07 06:35:30