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

React状态提升问题:子组件无法正确更新父组件cityObj状态

问题解决:React父子组件状态传递异常修复

核心错误点梳理

你的代码存在3个关键问题,直接导致cityObj状态要么undefined要么显示[object object]:

  1. 父组件传递错误的状态更新函数
    Search组件给Select传参时写了setCityObj={cityObj},这是把cityObj的状态值传了过去,而非更新状态的setCityObj函数,子组件调用时自然无法修改父组件的cityObj。

  2. 子组件props接收方式错误
    React组件的props是唯一入参,不能拆成两个参数接收。你写的function Select(props, {cityObj, setCityObj})不符合规范,所有props需从第一个参数中解构或通过props.xxx访问。

  3. 提交函数未执行+状态类型不匹配

  • 点击Submit时仅引用了handleSubmit函数,未执行,导致状态更新逻辑根本没触发;
  • 你通过拼接字符串传递城市信息,若想传递完整城市对象,需直接获取API返回的city对象,而非转成字符串,否则直接打印对象会显示[object object]。

修正后的代码

Search组件

function Search(props) {
    const [searchTerm, setSearchTerm] = React.useState('');
    const [cityArray, setCityArray] = React.useState([]);
    const [cel, setCel] = React.useState(null);
    const [cityObj, setCityObj] = React.useState(null); // 初始值设为null,匹配对象类型

    const Weather_API_key = '55c5392db030dbb75249aa1ff9b8a871';
    const url = 'http://api.openweathermap.org/geo/1.0/direct';

    const handleChange = (event) => {
        setSearchTerm(event.target.value);
    }

    const handleSubmit = (event) => {
        console.log('The form submitted with input: ' + searchTerm);
        setCel(() => (searchTerm - 32) / 1.8);
        event.preventDefault();
        fetch(`${url}?q=${searchTerm}&limit=5&appid=${Weather_API_key}&units=metric`)
            .then(response => response.json())
            .then(data => {
                console.log(data);
                setCityArray(data);
            });
    }

    return (
        <div className="container p-3 bg-success">
            <i className='text-danger fw-bold'>Search component</i>
            <form onSubmit={handleSubmit} className='my-3 row g-3'>
                <label className="col-sm-4 col-form-label">
                    Please enter city name:
                </label>
                <div className="col-sm-4">
                    <input type="text" value={searchTerm}
                        onChange={handleChange} className="form-control" />
                </div>
                <div className="col-sm-4">
                    <input type="submit" value="Search" className="btn btn-primary mb-3" />
                </div>
            </form>
            
            {/* 修正:传递状态更新函数setCityObj */}
            <Select cityArray={cityArray} cityObj={cityObj} setCityObj={setCityObj}/>
            <Body />
        </div>
    );
}

Select组件

// 修正:从第一个参数解构所有需要的props
function Select({ cityArray, cityObj, setCityObj }) {
    const [selectedCity, setSelectedCity] = React.useState(null); // 直接存储城市对象

    const handleChange = (event) => {
        // 根据选中项的索引获取对应的城市对象
        const selectedIndex = event.target.selectedIndex;
        const targetCity = cityArray[selectedIndex];
        setSelectedCity(targetCity);
        console.log("选中的城市对象:", targetCity);
    }

    const handleSubmit = (event) => {
        event.preventDefault();
        console.log('提交的城市:', selectedCity);
        // 将完整城市对象传递给父组件的cityObj状态
        setCityObj(selectedCity);
    }

    return (
        <div className="container p-3 bg-warning">
            <i className='text-danger fw-bold'>Select component</i>
            <form className='row g-3'>
                <label className="col-sm col-form-label">
                    Choose your country:</label>
                <select onChange={handleChange} className='form-select col-md'>
                    {cityArray.map((city, index) =>
                        <option key={city.name + index}>
                            {city.name}, {city.country}
                        </option>
                    )}
                </select>
                <div className="col-sm col-form-label">
                    {/* 修正:执行handleSubmit函数 */}
                    <a onClick={handleSubmit} href="#">Submit</a>
                </div>
            </form>

            {selectedCity && (
                <div> You selected {selectedCity.name}, {selectedCity.country} </div>
            )}
            
            {/* 验证父组件是否接收到状态 */}
            {cityObj && (
                <div>父组件已接收城市:{cityObj.name}, {cityObj.country}</div>
            )}
        </div>
    );
}

关键说明

  1. 父子组件通信规范:父组件必须传递状态更新函数给子组件,子组件通过调用该函数修改父组件状态,这是React父子组件通信的标准方式。
  2. props接收规范:React组件的所有props都包含在第一个参数中,可通过对象解构或props.xxx访问。
  3. 对象状态处理:若需传递完整对象,直接操作API返回的原始对象即可,避免转成字符串导致的[object object]问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.22 07:34:54