React多层子组件状态提升问题求助
解决React多层组件状态提升问题
要把Select选中的城市信息同步到Main组件的state,核心是通过回调函数逐层传递,把顶层的状态更新方法往下传给子组件,让子组件能触发顶层状态更新。具体修改步骤如下:
- Main组件:给Search传递更新cityObj的回调函数
- Search组件:接收回调函数并传递给Select
- Select组件:提交时通过回调把选中的完整城市对象传给Main
修改后的Main.js
function Main() { const [cityObj, setCityObj] = React.useState(null); // 初始值设为null更合理 return ( <div className="container p-5 bg-primary"> <i className='text-danger fw-bold'>Main component</i> <h2 className='m-3'>My React Weather Application</h2> {/* 传递setCityObj给Search,命名为onCitySelect */} <Search onCitySelect={setCityObj} /> <hr /> {/* 把cityObj传给Body组件使用 */} <Body cityObj={cityObj} /> </div> ); }
修改后的Search.js
function Search(props) { const [searchTerm, setSearchTerm] = React.useState(''); const [cityArray, setCityArray] = React.useState([]); // 清理冗余状态 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) => { 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> {/* 把onCitySelect传递给Select */} <Select cityArray={cityArray} onCitySelect={props.onCitySelect} /> </div> ); }
修改后的Select.js
function Select(props) { const [selectedIndex, setSelectedIndex] = React.useState(''); // 存选中的城市索引 const handleChange = (event) => { setSelectedIndex(event.target.value); } const handleSubmit = (event) => { event.preventDefault(); if (selectedIndex !== '') { // 根据索引拿到完整的城市对象 const selectedCity = props.cityArray[selectedIndex]; // 调用父组件传递的回调,把城市对象传给Main props.onCitySelect(selectedCity); } } return ( <div className="container p-3 bg-warning"> <i className='text-danger fw-bold'>Select component</i> <form onSubmit={handleSubmit} className=' row g-3'> <label className="col-sm col-form-label"> Choose your country:</label> <select value={selectedIndex} onChange={handleChange} className='form-select col-md'> {/* 用索引作为option的value,方便后续获取完整对象 */} {props.cityArray.map((city, index) => <option key={index} value={index}> {city.name}, {city.country} </option> )} </select> <div className="col-sm col-form-label"> <input type="submit" value="Submit" className="btn btn-primary mb-3" /> </div> </form> {props.cityArray[selectedIndex] && ( <div> You selected {props.cityArray[selectedIndex].name}, {props.cityArray[selectedIndex].country} </div> )} </div> ); }
关键修改说明
- 状态传递路径:通过props将Main的
setCityObj以onCitySelect为名逐层传递到Select,让最底层的子组件能直接触发顶层状态更新。 - 传递完整对象:Select不再存储字符串形式的城市信息,而是存储城市在数组中的索引,提交时获取完整的城市对象传给Main,确保Body组件能直接使用城市的经纬度等所有字段。
- 清理冗余状态:移除Search组件中无用的
cel和selectedCity状态,简化组件逻辑。
内容的提问来源于stack exchange,提问作者Adam
相关产品推荐
相关产品推荐

