本文譯自:30-seconds-of-react。React 30 秒速學:全篇中文翻譯、學習,地址:30-seconds-of-react-zh_CN-umi,全部案例進行分析、註釋、上線。react
系列文章:git
手風琴效果組件,包含多個可摺疊內容。github
AccordionItem
組件,將它傳遞給Accordion
。並經過在props.children
中識別函數的名稱來刪除AccordionItem
所需的沒必要要的節點。AccordionItem
組有一個<button>
,用於經過props.handleClick
回調更新Accordion
和組件的內容,經過props.children
向下傳遞,它的摺疊狀態由props.isCollapsed
肯定。Accordion
組件中,使用React.useState()
鉤子將bindIndex
狀態變量的值初始化爲props.defaultIndex
。Array.prototype.map
來渲染單個可摺疊的元素。changeItem
,它將在單擊AccordionItem
的<button>
時執行。 changeItem
執行傳遞的回調,onItemClick
並根據點擊的元素更新bindIndex
。AccordionItem 組件:數組
import React from "react";
function AccordionItem(props) {
const style = {
collapsed: {
display: "none"
},
expanded: {
display: "block"
},
buttonStyle: {
display: "block",
width: "100%"
}
};
return (
<div> {/* 按鈕,點擊傳入的 handleClick */} <button style={style.buttonStyle} onClick={() => props.handleClick()}> {props.label} </button> {/* 控制顯示、隱藏狀態 */} <div className="collapse-content" style={props.isCollapsed ? style.collapsed : style.expanded} aria-expanded={props.isCollapsed} > {/* 內容 */} {props.children} </div> </div>
);
}
複製代碼
Accordion 組件:app
function Accordion(props) {
// 目前顯示的 index
const [bindIndex, setBindIndex] = React.useState(props.defaultIndex);
// 點擊即把 bindIndex 設置爲本身
const changeItem = itemIndex => {
if (typeof props.onItemClick === "function") props.onItemClick(itemIndex);
if (itemIndex !== bindIndex) setBindIndex(itemIndex);
};
// 篩選出傳入的 AccordionItem 組件,忽略其餘
const items = props.children.filter(
// 組件名
item => item.type.name === "AccordionItem"
);
return (
<div className="wrapper"> {items.map(({ props }) => ( <AccordionItem isCollapsed={bindIndex === props.index} label={props.label} handleClick={() => changeItem(props.index)} children={props.children} /> ))} </div> ); } 複製代碼
export default function() {
return (
<Accordion defaultIndex="1" onItemClick={console.log}> <AccordionItem label="A" index="1"> Lorem ipsum </AccordionItem> <AccordionItem label="B" index="2"> Dolor sit amet </AccordionItem> </Accordion>
);
}
複製代碼