React对接天气API表单首次查询无数据、查询结果滞后问题求解
问题原因
fetch属于异步网络请求,触发后不会阻塞后续代码执行,你在请求发起后立刻调用props.onSubmit传递的weather还是请求发起前的旧值,首次提交时就是初始的空对象。- React的状态更新是异步批量执行的,执行
setWeather(result)后,当前函数执行周期内的weather变量不会立刻变更,必须等到组件下一次重渲染才能拿到最新值,所以你第二次提交时拿到的是第一次请求返回的结果,以此类推始终滞后一次。
修复代码
直接调整handleSubmit函数逻辑,把传递数据给父组件的操作放到fetch的成功回调里,直接使用接口返回的结果,不要依赖当前作用域的weather状态:
const handleSubmit = (e) => { e.preventDefault(); // 先做输入合法性校验,避免空请求 if (!input || /^\s*$/.test(input)) return; fetch(`${api.base}weather?q=${input}&appid=${api.key}&units=metric`) .then((res) => res.json()) .then((result) => { // 接口返回成功后再传递数据给父组件 props.onSubmit({ id: Math.floor(Math.random() * 10000), text: input, data: result, }); // 再更新本地状态,如果本地不需要用到weather状态可以删掉这行和对应的useState定义 setWeather(result); setInput(""); }) .catch(err => { // 可自行扩展错误提示逻辑,比如弹窗告知用户查询失败 console.error("天气查询失败:", err); setInput(""); }); };
额外优化点
- 你代码中定义的
query状态从未使用,可以直接删除对应useState声明 - 可以针对接口返回的异常状态做判断,比如城市不存在时给出对应提示
- 可以加请求加载状态,避免用户重复点击提交按钮
内容的提问来源于stack exchange,提问作者Mary Timms
相关产品推荐
相关产品推荐

