简介
在本实验中,我们将探索如何使用组件和钩子在 React 中实现一个可折叠的手风琴菜单。本实验的目的是提供一个实践经验,用于构建一个具有多个可折叠内容元素的功能性手风琴菜单。在本实验结束时,你将很好地理解如何使用 React 创建动态和交互式用户界面。
可折叠手风琴
VM 中已经提供了
index.html和script.js。一般来说,你只需要在script.js和style.css中添加代码。
要渲染一个带有多个可折叠内容元素的手风琴菜单,你可以按照以下步骤操作:
- 定义一个
AccordionItem组件,该组件渲染一个<button>,并在通过handleClick回调通知其父组件的同时更新组件。 - 在
AccordionItem中使用isCollapsed属性来确定其外观并设置其className。 - 定义一个
Accordion组件,并使用useState()钩子将bindIndex状态变量的值初始化为defaultIndex。 - 通过识别函数名称来过滤
children,以删除不必要的节点,AccordionItem除外。 - 对收集到的节点使用
Array.prototype.map()来渲染各个可折叠元素。 - 定义
changeItem,它将在点击AccordionItem的<button>时执行。 changeItem执行传递的回调onItemClick,并根据点击的元素更新bindIndex。
以下是代码:
.accordion-item.collapsed {
display: none;
}
.accordion-item.expanded {
display: block;
}
.accordion-button {
display: block;
width: 100%;
}
const AccordionItem = ({ label, isCollapsed, handleClick, children }) => {
return (
<>
<button className="accordion-button" onClick={handleClick}>
{label}
</button>
<div
className={`accordion-item ${isCollapsed ? "collapsed" : "expanded"}`}
aria-expanded={isCollapsed}
>
{children}
</div>
</>
);
};
const Accordion = ({ defaultIndex, onItemClick, children }) => {
const [bindIndex, setBindIndex] = React.useState(defaultIndex);
const changeItem = (itemIndex) => {
if (typeof onItemClick === "function") onItemClick(itemIndex);
if (itemIndex !== bindIndex) setBindIndex(itemIndex);
};
const items = children.filter((item) => item.type.name === "AccordionItem");
return (
<>
{items.map(({ props }) => (
<AccordionItem
isCollapsed={bindIndex !== props.index}
label={props.label}
handleClick={() => changeItem(props.index)}
children={props.children}
/>
))}
</>
);
};
ReactDOM.createRoot(document.getElementById("root")).render(
<Accordion defaultIndex="1" onItemClick={console.log}>
<AccordionItem label="A" index="1">
Lorem ipsum
</AccordionItem>
<AccordionItem label="B" index="2">
Dolor sit amet
</AccordionItem>
</Accordion>
);
请点击右下角的“Go Live”以在端口 8080 上运行 Web 服务。然后,你可以刷新“Web 8080”标签页来预览网页。
总结
恭喜你!你已经完成了可折叠手风琴实验。你可以在 LabEx 中练习更多实验来提升你的技能。