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

React异步函数刷新页面后返回undefined,编译后恢复正常

问题原因拆解

1. console.log(data) 显示undefined

React的setState是异步批量更新机制,调用setData(responseData)后,组件不会立刻重新渲染,当前函数作用域里的data还是初始的undefined(闭包保留了当前渲染周期的state值)。所以你紧接着打印的data是旧值,并非刚设置的新数据。

2. responseData 打印两次

这是React 18开发环境下Strict Mode的特性:它会自动执行两次副作用(比如useEffect内的代码),用来检测组件是否存在副作用泄漏、非幂等操作等潜在问题。刷新页面时触发完整的组件初始化流程,所以会触发两次;而webpack热重载时是组件增量更新,Strict Mode的重复执行逻辑未触发,因此只打印一次。生产环境下该行为会自动消失。

解决办法

针对console.log(data) undefined的问题

不要在setData后立即打印,而是通过useEffect监听data的变化,待data更新完成后再打印:

useEffect(() => {
  if (data) {
    console.log(data);
  }
}, [data]); // 依赖data,仅当data变化时执行

或者理解异步更新特性:新的data会在组件下一次渲染时生效,之后在JSX或其他依赖data的逻辑中直接使用即可。

针对两次打印的问题

这是开发环境的调试特性,生产环境不会出现。如果觉得开发时看着烦,可以暂时关闭项目根组件的StrictMode包裹(比如index.js里的<React.StrictMode>),但不推荐长期这么做——Strict Mode能帮你提前发现很多潜在bug。如果你的副作用是幂等的(比如这个fetch请求,重复调用无不良影响),完全可以忽略该现象。

修改后的完整代码示例

import React, { useEffect, useState } from "react";

const endpointUrl = "https://api.binance.com/api/v3/klines?symbol=BTCUSDT&interval=1h&limit=5";

const Test = () => {
    const [data, setData] = useState();

    useEffect(() => {
        const fetchApi = async () => {
            const response = await fetch(endpointUrl);
            const responseData = await response.json();
            console.log(responseData);
            setData(responseData);
        };
        fetchApi().catch(console.error);
    }, []);

    // 监听data变化,更新后打印
    useEffect(() => {
        if (data) {
            console.log("更新后的data:", data);
        }
    }, [data]);

    return (
        <div>
            <ul>
                {data ? data.map((item, index) => (
                    <li key={index}>{new Date(item[0]).toLocaleString()}</li> // 示例渲染格式化后的时间
                )) : "Loading..."}
            </ul>
        </div>
    );
};

export default Test;

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.20 03:10:36