React中AJAX存数据到state后控制台打印为空数组问题
问题原因与解决方案
嗨,这个问题我太熟悉啦!你遇到的是React里异步操作的典型坑🤓,咱们一步步来拆解:
为什么会打印空数组?
- fetch是异步请求:你调用fetch后,代码会立刻往下执行
console.log,这时候网络请求还在后台跑,根本没拿到返回数据,setState自然也还没执行,所以打印的是初始的空数组。 - setState本身也是异步的:就算你把
console.log写在setState的下一行,也不一定能拿到最新的state——React会把state更新放进队列,等合适的时机批量更新,不会立刻修改state的值。
两种解决办法
方法1:用setState的回调函数
setState支持第二个参数,这是一个回调函数,会在state真正更新完成后执行,刚好适合用来打印最新的state:
state = { addressOject: [] }; view = value => { fetch('http://127.0.0.1:8000/api/addresses/show/'+ value, { method: 'GET', headers: { 'Accept': 'application/json', 'Content-Type': 'application/json', 'Authorization': 'Bearer ' + Auth.getToken(), } // 注意:GET请求不需要body,这里可以删掉原来的body行哦 }) .then((response) => response.json()) .then((responseData) => { // 在这里添加setState的回调 this.setState({ addressOject: responseData.data[0] }, () => { console.log(this.state.addressOject); // 现在能拿到最新数据啦! }); }) // 别忘了加catch处理请求错误,避免出问题没提示 .catch(error => console.error('请求出错啦:', error)); }
方法2:改用async/await语法
如果觉得then链看着麻烦,用async/await可以让异步代码看起来像同步的,更直观:
state = { addressOject: [] }; // 把函数标记为async view = async value => { try { const response = await fetch('http://127.0.0.1:8000/api/addresses/show/'+ value, { method: 'GET', headers: { 'Accept': 'application/json', 'Content-Type': 'application/json', 'Authorization': 'Bearer ' + Auth.getToken(), } }); const responseData = await response.json(); await this.setState({ addressOject: responseData.data[0] }); console.log(this.state.addressOject); // 这里能拿到最新state } catch (error) { console.error('请求出错啦:', error); } }
额外小提示
GET请求一般不需要设置body,你原来代码里的body: JSON.stringify()可以删掉,不然可能会导致服务器解析请求时出现异常哦~
内容的提问来源于stack exchange,提问作者abu abu
相关产品推荐
相关产品推荐

