React.js中如何获取一个JSON响应后调用另一JSON接口获取数据
核心问题点
你的代码逻辑存在以下几个本质错误,导致链式API调用失败:
- 两个Axios请求是并行触发的,没有等待地理编码接口返回经纬度结果就直接发起天气请求,此时经纬度还是初始值
0,根本无法定位到目标位置 - React的state更新是异步批处理的,调用
setState后立刻读取原state变量,拿到的还是更新前的旧值;且你把经纬度赋值逻辑写在了天气请求的回调里,顺序完全颠倒——天气请求都发出去了才给经纬度赋值,没有任何作用 - 输入框
onChange事件里用&&做逻辑短路是错误写法:setState函数没有返回值(返回undefined,属于假值),后面写的setLatitude、setLongitude永远不会执行;而且经纬度是接口返回的,不需要在用户输入时手动修改 - 地理编码接口用了
http协议,现代浏览器默认拦截非HTTPS的混合内容请求,会直接导致接口调用失败 - 用了已经被Web标准废弃的
onKeyPress事件,不同浏览器下兼容性很差;input上写的searchWeather是非法自定义属性,没有任何作用
修正后可运行代码
import React, { useState } from 'react' import axios from 'axios' function App() { const [data, setData] = useState({}) const [postalcode, setPostalCode] = useState('') const [latitude, setLatitude] = useState(0) const [longitude, setLongitude] = useState(0) const searchPostalCode = async (event) => { if (event.key === 'Enter') { try { // 第一步:根据邮政编码请求经纬度 const geoResponse = await axios.get(`https://api.openweathermap.org/geo/1.0/zip?zip=${postalcode},CA&limit=1&appid=7fe57d3d219cd9512845e116e4c353c5`) const { lat, lon } = geoResponse.data setLatitude(lat) setLongitude(lon) // 第二步:拿到经纬度后请求天气数据 const weatherResponse = await axios.get(`https://api.openweathermap.org/data/2.5/weather?lat=${lat}&lon=${lon}&units=metric&appid=7fe57d3d219cd9512845e116e4c353c5`) setData(weatherResponse.data) // 清空输入框 setPostalCode("") } catch (error) { console.error('请求失败,请检查邮政编码是否正确', error) // 可自行添加错误提示UI逻辑 } } } return ( <div className="app"> <div className="search"> <input value={postalcode} onChange={event => setPostalCode(event.target.value)} onKeyDown={searchPostalCode} placeholder='Enter Postal Code' type="text" /> </div> {/* 后续天气展示UI可保留原有逻辑 */} </div> ); } export default App;
入门学习建议
- 先打牢JS异步基础:把Promise、async/await的执行顺序搞明白,有先后依赖的异步操作必须等前一个操作返回结果后再执行下一个,不能同步并行写
- 牢记React state的异步特性:不要在调用
setState后立刻读取同一个state的值,此时拿到的一定是旧值;如果需要用到更新后的值,直接用触发更新的源数据(比如这里接口直接返回的lat、lon),或者用useEffect监听state变化后再执行后续逻辑 - 不要滥用
&&做逻辑短路,只有前半段表达式返回真值时后半段才会执行,写逻辑前先确认每一步的返回值是什么 - 前端调用第三方接口优先用HTTPS协议,避免被浏览器安全策略拦截
- 调试链式请求时,每拿到一个接口的响应就先打印到控制台,确认数据结构符合预期后再写下一段逻辑,不要一口气写完所有逻辑再排错
- 注意:你现在把API密钥直接硬编码在前端代码里,练习阶段无所谓,生产环境一定要把密钥存在服务端,通过后端代理请求接口,否则密钥会被直接窃取
内容的提问来源于stack exchange,提问作者FlamingNinja925
相关产品推荐
相关产品推荐

