如何仅切换特定组件显隐,不影响共用同一State的其他组件
解决方案
你可以通过以下两种常用方式实现需求:
方式1:父组件维护展开状态集合
适用场景:需要在父组件获取所有展开项状态的场景
- 替换原布尔状态为展开项集合(支持多项目同时展开)
// 原代码 const [click,setClick] = useState(false) // 替换为 const [expandedSet, setExpandedSet] = useState(new Set())
- 修改点击事件逻辑,仅修改当前点击项的状态
onClick={() => { const newExpandedSet = new Set(expandedSet) newExpandedSet.has(index) ? newExpandedSet.delete(index) : newExpandedSet.add(index) setExpandedSet(newExpandedSet) }}
- 修改
HiddenText和ReadButton的状态判断逻辑,仅匹配当前项的索引
<HiddenText click={expandedSet.has(index)}> <ReadButton NeedButton={data.NeedButton} click={expandedSet.has(index)} {/* 此处插入修改后的onClick逻辑 */} > { expandedSet.has(index) ? 'Read Less' : 'Read More' } </ReadButton>
如果需要仅允许同时展开一个项,可以把状态改为存储当前展开的索引即可:
const [activeIndex, setActiveIndex] = useState(null) // 点击事件 onClick={() => setActiveIndex(activeIndex === index ? null : index)} // 状态判断逻辑 click={activeIndex === index}
方式2:封装独立子组件,内部维护私有状态
适用场景:无父组件获取展开状态需求的场景,逻辑更解耦
把每个遍历渲染的内容项抽为单独的ContentItem组件,每个组件内部维护自己的展开状态,天然不会互相干扰:
// 抽离的子组件 const ContentItem = ({ data }) => { const [click, setClick] = useState(false) return ( <Content> <p className="first-content"> <BigContainer imgStart={data.imgStart}> <Wrapper> <Solution>{data.Solution}</Solution> <Client>{data.Client}</Client> <ShowText>{data.ShowText}</ShowText> <HideTextWrapper NeedToHide={data.NeedToHide} > <HiddenText click={click}> {data.HiddenText} </HiddenText> <ReadButton NeedButton={data.NeedButton} click={click} onClick={()=>setClick(!click)} > { click ? 'Read Less' : 'Read More' } </ReadButton> </HideTextWrapper> </Wrapper> <ImageWrapper> <Image src={data.img} NeedImage={data.NeedImage}/> </ImageWrapper> </BigContainer> </p> </Content> ) } // 父组件遍历部分修改为 {Data.Data.map((data, index) => <ContentItem key={index} data={data} />)}
注意事项
如果Data数组存在增删、排序的操作,建议使用数组项的唯一业务id(而非遍历index)作为key和状态匹配的标识,避免出现状态错位的问题。
内容的提问来源于stack exchange,提问作者Woppy
相关产品推荐
相关产品推荐

