React.js使用Hook开发点击城市展示下属区域的组件传值与功能实现问题

需求:点击顶部城市按钮后,底部展示该城市下辖的子区域。
现有代码问题
- 父组件向子组件传值错误:当前传给
SubArea的是subArea函数本身,不是处理好的子区域数据,且存储子区域的areaList是普通变量,更新不会触发组件重渲染 - 子区域计算逻辑错误:用
while循环计算长度时从下标1开始,会漏掉第一个子区域数据 - 子组件渲染逻辑错误:未调用
areaBtn函数就直接渲染,且生成按钮时错误读取tmp[i]作为文本,实际应该读取传入的list[i] - 未遵循React列表渲染规范:列表元素没有添加
key属性
修复后的代码
父组件 Restaurant.jsx
import React, {useState} from 'react'; import {Link} from "react-router-dom"; import axios from 'axios'; import SubArea from './SubArea'; // 请补充导入你项目里的backicon资源 import backicon from '你的backicon文件路径' const Restaurant = () => { // 用state存储选中城市对应的子区域列表,状态更新会触发重渲染 const [subAreaList, setSubAreaList] = useState([]); const serviceKey = "myserviceKey"; // 替换为你的服务密钥 const api = (code) => { const url = `http://api.visitkorea.or.kr/openapi/service/rest/KorService/areaCode?ServiceKey=${serviceKey}&areaCode=${code}&numOfRows=10&pageNo=1&MobileOS=ETC&MobileApp=AppTest`; axios .get(url) .then((res) => { console.log("SUCCESS"); const areaCode = res.data.response.body.items.item; // 直接提取区域名称数组,更新状态 const nameList = areaCode.map(item => item.name); setSubAreaList(nameList); }) } return ( <div> <Link to="./"><img className="backicon" src={backicon} alt="backicon"/></Link> <h1 className="header2">위치설정</h1> <p className="normalfont">찾고 싶은 위치 및 장소를 입력하세요</p> <div className="btn_class"> <form action="search.php" method="post"> <input className="btn_text" type="text"/> <input className="btn_submit" type="submit" value="SEARCH"/> </form> </div> <p className="findingplace">광역시</p> <div className="containerList"> <button className="itemList" onClick={() => api(1)} >서울시</button> <button className="itemList" onClick={() => api(2)} >인천시</button> <button className="itemList" onClick={() => api(3)} >대전시</button> {/* 其余城市按钮取消注释即可使用 */} </div> <p className="findingplace">시/군/구</p> <div className="containerList2"> {/* 直接传递子区域数组给子组件 */} <SubArea list={subAreaList} /> </div> </div> ); }; export default Restaurant;
子组件 SubArea.jsx
const SubArea = ({list}) => { console.log(list) const renderAreaBtn = () => { // 空状态提示 if (!list || list.length === 0) { return <p>请先选择上方城市</p> } const btnList = []; for (let i = 0; i < list.length; i++) { btnList.push(<button key={i} className="itemList2">{list[i]}</button>) } return btnList; } return ( <div className="containerList2"> {/* 调用渲染函数拿到节点 */} {renderAreaBtn()} </div> ); }; export default SubArea;
核心调整说明
- 父组件用
useState存储子区域列表,状态更新会自动触发组件重渲染,子组件同步接收最新数据 - 删除了冗余的长度计算逻辑,直接用数组
map方法提取区域名称,避免漏读第一个元素的问题 - 父子组件职责拆分清晰:父组件负责请求数据、处理数据,子组件只负责接收数组渲染列表
- 修复了子组件渲染逻辑错误,补充空状态提示,列表添加
key属性符合React规范
内容的提问来源于stack exchange,提问作者C12H22O12
相关产品推荐
相关产品推荐

