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
相关产品推荐
相关产品推荐

