React垂直嵌套列表问题:点击单个州仅展开对应区县子列表
解决React州/区县列表点击单个展开的问题
你当前的核心问题是:所有州组件共用了同一个全局open状态,导致点击任意州时,所有子列表都会同步展开/收起。下面提供两种实用的解决方式,同时修正你代码里的语法和变量名错误。
方案1:每个州组件独立维护展开状态
把展开状态下沉到StateList组件内部,让每个州自己管理是否展开,互不干扰。
修正后的完整代码:
import React, { useState } from "react" // 区县组件 const AreaList = ({ state }) => { return ( <ul> {state.districts.map((district, idx) => ( <li key={idx}> <span className="ml-2 text-outer-space">{district.name}</span> </li> ))} </ul> ) } // 州组件 const StateList = ({ state }) => { // 每个州独立的展开状态 const [isOpen, setIsOpen] = useState(false) return ( <div onClick={() => setIsOpen(!isOpen)}> <span>{state.name}</span> <svg viewBox="0 0 24 24" className={`${isOpen ? "rotate-180" : ""}`} > {/* 可添加箭头图标路径,例:<path d="M7 10l5 5 5-5z" /> */} </svg> {isOpen && <AreaList state={state} />} </div> ) } // 父容器组件 const StateDistrictWrapper = ({ states }) => { return ( <div> {states.map((state, index) => { return <StateList state={state} key={index} />; })} </div> ) } export default StateDistrictWrapper
方案2:父组件统一管理展开状态
如果需要父组件控制或追踪展开的州,可以在父组件中存储当前展开的州唯一标识(比如ID),子组件根据标识判断是否展开。
修正后的代码:
import React, { useState } from "react" // 区县组件 const AreaList = ({ state }) => { return ( <ul> {state.districts.map((district, idx) => ( <li key={idx}> <span className="ml-2 text-outer-space">{district.name}</span> </li> ))} </ul> ) } // 州组件 const StateList = ({ state, expandedStateId, setExpandedStateId }) => { const isOpen = expandedStateId === state.id // 假设每个州有唯一id字段 const toggleOpen = () => { // 点击时切换:已展开则收起,未展开则展开当前州 setExpandedStateId(expandedStateId === state.id ? null : state.id) } return ( <div onClick={toggleOpen}> <span>{state.name}</span> <svg viewBox="0 0 24 24" className={`${isOpen ? "rotate-180" : ""}`} > {/* 可添加箭头图标路径 */} </svg> {isOpen && <AreaList state={state} />} </div> ) } // 父容器组件 const StateDistrictWrapper = ({ states }) => { // 存储当前展开的州id,初始为null(全部收起) const [expandedStateId, setExpandedStateId] = useState(null) return ( <div> {states.map((state, index) => { return ( <StateList state={state} key={index} expandedStateId={expandedStateId} setExpandedStateId={setExpandedStateId} /> ); })} </div> ) } export default StateDistrictWrapper
原代码的额外错误修正
- 变量名混淆:
states.map((city, index)里的city建议改为state,避免和子组件props冲突;原代码中StateList state={state}实际应为state={city}(若保留city变量名) - 语法错误:
Const需改为小写const,[open,,setOpen]多余的逗号要删除 - Props传递错误:
AreaList area={city}应改为state={city},匹配AreaList接收的参数 - 标签不闭合:原代码中存在多余的
</h2>和未闭合标签,需修正
内容的提问来源于stack exchange,提问作者Andaman
相关产品推荐
相关产品推荐

