You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React修改state后组件不重新渲染:天气应用开发问题求助

问题原因&修复方案

1. 阻止表单默认提交行为

你的搜索按钮是type="submit",放在form标签内点击会触发浏览器默认表单提交,导致页面重载回到初始状态,需要在提交事件里调用e.preventDefault()阻止默认行为。

2. 正确获取搜索框输入内容

你没有给搜索框绑定受控状态,点击提交时无法拿到用户输入的地区名,需要在Navbar组件内维护输入框的状态,提交时把值传给父组件的setPlaceName。

3. 修复prop名冲突问题

App.js中给Display组件传递的API密钥用了key作为prop名,key是React的保留属性,不会传递到组件内部的props对象中,需要修改为自定义名称比如apiKey。

4. 让Display组件响应placeName变化

当前Display的useEffect依赖项是空数组,仅会在组件首次挂载时请求接口,当placeName prop更新时不会重新拉取数据,需要把props.placeName添加到useEffect的依赖数组中。


修正后的代码

App.js

import React,{useState} from 'react';
import Navbar from './Navbar.js';
import Display from './Display.js'
function App() {
  const[placeName,setPlaceName] = useState('Raipur')
  const apiKey = 'not gonna tell';

  return (
   <>
   <Navbar setPlaceName={setPlaceName} />
   <Display apiKey={apiKey} placeName={placeName} />
   </>
  );
}

export default App;
import React, { useState } from 'react';

function Navbar(props) {
  const [searchVal, setSearchVal] = useState('');

  const handleSubmit = (e) => {
    e.preventDefault();
    if (searchVal.trim()) {
      props.setPlaceName(searchVal.trim());
    }
  }

  return(
   <>
    <nav className="navbar navbar-expand-lg navbar-dark bg-dark">
  <div className="container-fluid">
    <a className="navbar-brand" href="/">Navbar</a>
    <button className="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="/navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">
      <span className="navbar-toggler-icon"></span>
    </button>
    <div className="collapse navbar-collapse" id="navbarSupportedContent">
      <ul className="navbar-nav me-auto mb-2 mb-lg-0">
        <li className="nav-item">
          <a className="nav-link active" aria-current="page" href="/">Home</a>
        </li>
        <li className="nav-item">
          <a className="nav-link" href="/">Link</a>
        </li>
        <li className="nav-item dropdown">
          <a className="nav-link dropdown-toggle" href="/" id="navbarDropdown" role="button" data-bs-toggle="dropdown" aria-expanded="false">
            Dropdown
          </a>
          <ul className="dropdown-menu" aria-labelledby="navbarDropdown">
            <li><a className="dropdown-item" href="/">Action</a></li>
            <li><a className="dropdown-item" href="/">Another action</a></li>
            <li><hr className="dropdown-divider"/></li>
            <li><a className="dropdown-item" href="/">Something else here</a></li>
          </ul>
        </li>
        <li className="nav-item">
          <a className="nav-link disabled">Disabled</a>
        </li>
      </ul>
      <form className="d-flex" onSubmit={handleSubmit}>
        <input 
          className="form-control me-2" 
          type="search" 
          placeholder="Search" 
          aria-label="Search"
          value={searchVal}
          onChange={(e) => setSearchVal(e.target.value)}
        />
        <button className="btn btn-outline-success" type="submit">Search</button>
      </form>
    </div>
  </div>
</nav>
   </>
  );
}

export default Navbar;

Display.js

import React,{useState,useEffect} from 'react';

function Display(props) {
  
  const[weatherInfo,setWeatherInfo] = useState({});
  
  const getWeatherInfo = async () =>{
    if (!props.placeName) return;
    try {
      let url =`https://api.weatherapi.com/v1/current.json?key=${props.apiKey}&q=${props.placeName}&aqi=no`;
      let res = await fetch(url);
      let parsedRes = await res.json();
      setWeatherInfo(parsedRes.location || {});
    } catch (err) {
      console.error('请求天气数据失败', err);
      setWeatherInfo({});
    }
  }

  useEffect(() =>{
    getWeatherInfo();
  },[props.placeName])
  return (
    <>
    <div className="container">
    <div className="row"> 
    {Object.values(weatherInfo).map((val, idx)=>{
    return(
     <div className="col" key={idx}>
     {val} 
     </div>
    )  
    })} 
    </div>
    </div>
    </>
  )
}

export default Display;

内容的提问来源于stack exchange,提问作者arsh coding

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.04 07:39:02