背景
クリックしたら開いて閉じるというただ単純な実装が、色々なコンポーネントに散乱しだしていたので、汎用的にその機能を使えるコンポーネントを実装してみました。
実装
import React, { useState } from 'react'
const SimpleAccordion = ({
defaultShow = false,
onOpen,
onClose,
...props
}) => {
const [show, setShow] = useState(defaultShow)
const toggle = () => {
const toggled = !show
setShow(toggled)
toggled ? onOpen && onOpen() : onClose && onClose()
}
const display = show ? 'block' : 'none'
return (
<React.Fragment>
{props.children.map((child, idx) =>
child.props.name === 'SimpleAccordionSummary' ? (
<div key={idx} onClick={toggle}>
{child}
</div>
) : child.props.name === 'SimpleAccordionDetails' ? (
<div key={idx} style={{ display }}>
{child}
</div>
) : null
)}
</React.Fragment>
)
}
const SimpleAccordionSummary = ({ children }) => (
<React.Fragment>{children}</React.Fragment>
)
const SimpleAccordionDetails = ({ children }) => (
<React.Fragment>{children}</React.Fragment>
)
SimpleAccordionSummary.defaultProps = {
name: 'SimpleAccordionSummary'
}
SimpleAccordionDetails.defaultProps = {
name: 'SimpleAccordionDetails'
}
export { SimpleAccordion, SimpleAccordionSummary, SimpleAccordionDetails }
実用例
const Sample = () => (
<React.Fragment>
<SimpleAccordion>
<SimpleAccordionSummary>
<p>概要</p> {/* ここをクリックすると開いたり閉じたりする */}
</SimpleAccordionSummary>
<SimpleAccordionDetails>
<p>詳細</p>
</SimpleAccordionDetails>
</SimpleAccordion>
</React.Fragment>
)