如何存储Axios请求的响应数据?两种实现方案的问题咨询
问题背景
我尝试存储Axios请求的响应数据,目前只有方案1可以正常运行。
方案1:通过state存储,运行正常
const [loadingData, setLoadingData] = useState(true); const [data, setData] = useState([]); useEffect(() => { async function getData() { await axios .get("sampleApi") .then((response) => { setData(response.data); setLoadingData(false); }); } if (loadingData) { getData(); } }, []); // 从state取数渲染运行正常 {data.map( (i, index) => { return <p key={index}>{i.id}</p> } )}
方案2:尝试使用普通变量而非state存储数据
const [loadingData, setLoadingData] = useState(true); let data; useEffect(() => { async function getData() { await axios .get("sampleApi") .then((response) => { data = response.data // <====== 此处赋值 setLoadingData(false); }); } if (loadingData) { getData(); } }, []); // 运行以下代码报错:Uncaught TypeError: Cannot read properties of undefined (reading 'map') {data.map( (i, index) => { return <p key={index}>{i.id}</p> } )}
问题解答
问题1:仅需要读取数据不会修改,存在state中是否是不好的开发实践?
不是,这是React标准的正确做法。
React组件只有在state、props变化或者父组件重渲染时才会触发重渲染。你从接口拿到的异步数据需要展示到页面上,必须在数据返回后触发一次重渲染才能更新视图,state就是专门用来存储这类需要响应到视图的数据的,哪怕你后续不会修改它,只要需要渲染动态获取的异步数据,就应该存在state里,完全不属于坏实践。
问题2:第二种实现方案存在什么问题?
核心问题是违背了React的渲染更新逻辑,具体有两点:
- 普通变量赋值不会触发组件重渲染
接口请求是异步操作,组件第一次渲染时接口还没返回结果,此时data是初始化的undefined,调用map方法自然会报错。就算你加了可选链data?.map避免报错,等接口返回给data赋值后,React感知不到普通变量的变化,不会触发重渲染,页面永远不会渲染出拿到的数据。 - 普通变量无法在组件重渲染后留存值
只要组件因为其他原因触发重渲染(比如其他state变化、父组件重渲染),你在组件内声明的let data都会被重新初始化回undefined,之前异步赋值的结果会直接丢失,根本存不住数据。
内容的提问来源于stack exchange,提问作者zenzone
相关产品推荐
相关产品推荐

