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

React中fetch获取数据导出遇只读错误的解决求助

解决React中异步数据获取与导出的问题

首先咱们来拆解你遇到的两个核心问题:

1. "data is read-only" 错误原因

你用const声明了data变量,const的特性就是一旦声明就不能被重新赋值,但你在fetch的then回调里写了data = obj,这就试图修改const变量,自然会抛出只读错误。

2. 数据未被正确获取的原因

fetch是异步操作,当你执行const RECORD_NOS=Object.keys(data).length-1;的时候,fetch还在后台请求数据,此时data还是你最初定义的箭头函数,根本不是请求回来的JSON对象,所以这行代码完全拿不到正确的结果。


正确的实现方式

我们需要处理异步逻辑,同时保证数据能在React组件中被正确复用。这里给你两种常用方案:

方案一:导出一个返回Promise的函数,在组件中异步获取

这种方式最灵活,也符合React的异步数据处理习惯:

// src/resources/index.js
export const fetchData = async () => {
  const response = await fetch("https://api.myjson.com/bins/mp441");
  const data = await response.json();
  return data;
};

// 如果你需要记录数,可以在获取数据后计算,比如在组件里:
// const data = await fetchData();
// const recordNos = Object.keys(data).length - 1;

在React组件中使用时(比如用useEffect处理异步):

import { fetchData } from './resources';

function MyComponent() {
  const [data, setData] = useState(null);
  const [recordNos, setRecordNos] = useState(0);

  useEffect(() => {
    const loadData = async () => {
      const fetchedData = await fetchData();
      setData(fetchedData);
      setRecordNos(Object.keys(fetchedData).length - 1);
    };
    loadData();
  }, []);

  if (!data) return <div>Loading...</div>;

  // 后续使用data和recordNos
  return <div>Total records: {recordNos}</div>;
}

方案二:在模块中初始化数据,导出数据和记录数(带缓存)

如果你希望数据只请求一次,然后在多个组件中复用,可以用这种方式:

// src/resources/index.js
let cachedData = null;
let cachedRecordNos = 0;

export const initData = async () => {
  if (cachedData) return; // 避免重复请求
  const response = await fetch("https://api.myjson.com/bins/mp441");
  cachedData = await response.json();
  cachedRecordNos = Object.keys(cachedData).length - 1;
};

// 导出获取数据的方法
export const getData = () => cachedData;
export const getRecordNos = () => cachedRecordNos;

在React组件中使用:

import { initData, getData, getRecordNos } from './resources';

function MyComponent() {
  const [data, setData] = useState(null);
  const [recordNos, setRecordNos] = useState(0);

  useEffect(() => {
    const loadData = async () => {
      await initData();
      setData(getData());
      setRecordNos(getRecordNos());
    };
    loadData();
  }, []);

  if (!data) return <div>Loading...</div>;

  return <div>Total records: {recordNos}</div>;
}

额外提示

  • 永远记住:异步操作不会立即返回结果,必须通过then或者async/await等待它完成。
  • const用于声明不会被重新赋值的变量,如果需要修改,应该用let(但在你的场景里,更推荐上面的方案,而不是直接修改变量)。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 03:57:15