React Native中Fetch API外部访问赋值变量返回Undefined值问题
问题根本原因
fetch为异步API,代码执行时不会等待网络请求返回结果,会直接执行fetch之后的同步代码(也就是你写的console.log('currentHMR', currentHMR)),此时then回调内的变量赋值逻辑还未运行,因此读取到的变量值为undefined。
问题其他隐藏缺陷
- 你定义的局部变量仅在当前作用域生效,就算赋值成功,也无法触发组件重新渲染,若该值需要在UI展示,后续还是无法正常使用。
- 网络请求存在失败概率,你没有在catch回调里停止加载动画,会出现请求失败后加载动画一直展示的问题。
修复方案
方案1:使用async/await写法(推荐,可读性更高)
将请求方法改为异步函数,等待请求返回后再执行后续逻辑,同时将结果存入state方便后续使用:
// 发起请求的方法需添加async修饰 const fetchDieselHmrData = async () => { const { diesel_data } = this.state; const asset_id = diesel_data[0].diselRequisitionDetails[0].asset_id; const current_hmr = diesel_data[0].diselRequisitionDetails[0].current_hmr; const requisitionId = diesel_data[0].requisitionId; this._indicator.startActivity(); try { const response = await fetch( `${url}Norms/DieselHmrViolation/${asset_id}/${current_hmr}/${requisitionId}`, { method: 'GET', headers: { 'Content-Type': 'application/json', }, } ); const list = await response.json(); this._indicator.stopActivity(); if (!isBlank(list)) { // 结果存入state,更新后会触发组件重渲染 this.setState( { currentHMR: list.currentHMR, previous_HMR: list.previous_HMR, previous_EstEngHours: list.previous_EstEngHours, isViolationPass_HMR: list.isViolationPass_HMR, }, () => { // setState回调可拿到最新的state值,执行依赖这些值的后续逻辑 console.log('currentHMR', this.state.currentHMR); } ); } } catch (error) { this._indicator.stopActivity(); console.error(error); } };
方案2:保持原有Promise写法,将依赖请求结果的逻辑移入回调
所有需要用到请求返回值的代码,都写在then回调内部:
const { diesel_data } = this.state; const asset_id = diesel_data[0].diselRequisitionDetails[0].asset_id; const current_hmr = diesel_data[0].diselRequisitionDetails[0].current_hmr; const requisitionId = diesel_data[0].requisitionId; this._indicator.startActivity(); fetch(`${url}Norms/DieselHmrViolation/${asset_id}/${current_hmr}/${requisitionId}`, { method: 'GET', headers: { 'Content-Type': 'application/json', }, }) .then((response) => response.json()) .then((json) => { this._indicator.stopActivity(); const list = json; console.log(list); if (!isBlank(list)) { const currentHMR = list.currentHMR; const previous_HMR = list.previous_HMR; const previous_EstEngHours = list.previous_EstEngHours; const isViolationPass_HMR = list.isViolationPass_HMR; // 所有依赖上述变量的逻辑都放在这里执行 console.log('currentHMR', currentHMR); // 需要在UI使用则存入state this.setState({ currentHMR, previous_HMR, previous_EstEngHours, isViolationPass_HMR, }); } }) .catch((error) => { this._indicator.stopActivity(); console.error(error); });
注意事项
- 异步请求的返回结果如果需要在组件其他位置或者UI上使用,必须存入组件state,不要使用局部变量存储。
- 所有依赖异步请求结果的逻辑,必须放在异步回调(then回调、await之后的代码、setState回调)中执行,不能放在和fetch同级的同步代码位置。
内容的提问来源于stack exchange,提问作者Mahesh Amte
相关产品推荐
相关产品推荐

