React TypeScript中如何修改数组内图标实现手风琴点击切换效果
手风琴组件优化方案
核心问题梳理
- 直接修改原始
accordionList数组的对象属性不属于React受控状态更新,不会触发组件重渲染,因此图标修改不会生效 - 原
icon全局单一状态设计不合理,无法支持多个手风琴项的独立状态控制 - 缺少手风琴内容展开/收起的显隐控制逻辑
优化后代码实现
App.tsx
import { useState } from 'react'; import { Accordion } from './Accordion'; // 静态配置数据,无需直接修改 const accordionList = [ { title: "Horses can...", icon: "🐴" }, { title: "Rhino skin maybe..", icon: "🦏" }, { title: "If you looking...", icon: "🦄" } ] function App() { // 记录当前展开的手风琴项索引,-1代表全部收起 const [activeIndex, setActiveIndex] = useState<number>(-1); // 优化后的切换逻辑 const toggleAccordion = (index: number) => { // 如果点击的是当前已展开的项则收起,否则展开点击的项 setActiveIndex(prev => prev === index ? -1 : index); } return ( <div className="App"> <div className="App-header"> {accordionList.map((accordion, index) => ( <ul className="accordion-list" key={index}> <div className="accordion-item"> <button onClick={() => toggleAccordion(index)}> {accordion.icon} {/* 直接根据激活状态渲染对应图标 */} {index === activeIndex ? '👇' : '👈'} </button> <Accordion accordion={accordion} isOpen={index === activeIndex} /> </div> </ul> ))} </div> </div> ); } export default App;
Accordion.tsx
interface Props { accordion: { title: string, icon: string; }, // 新增展开状态控制属性 isOpen: boolean } export const Accordion: React.FC<Props> = (props) => { const { accordion, isOpen } = props; return ( // 可通过CSS transition实现下滑展开动画 <div className={`accordion-content ${isOpen ? 'open' : ''}`}> {isOpen && accordion.title} </div> ) };
可选下滑动画CSS补充
添加以下CSS即可实现平滑的下滑展开效果:
.accordion-content { max-height: 0; overflow: hidden; transition: max-height 0.3s ease; } .accordion-content.open { max-height: 100px; /* 可根据实际内容高度调整 */ }
内容的提问来源于stack exchange,提问作者Nhan Nguyen
相关产品推荐
相关产品推荐

