Compositionを使って、Dialogを作ってみる

<h2>compositionとは</h2>
compositionとは、コンポーネントの中に別のコンポーネントを合成して出力することです。<br>
どんなコンポーネントはどんな子エレメントが入ってくるかあらかじめ想定できない場合がありますが、
例えば、dialogがあります。

<h2>compositionを使ったdialog</h2>
下のロジックは、ThankyouDialogがDialogにpropsを渡して、Dialogを出力しています。<br>
しかし、dialogは汎用的な特徴を持っているので、下の例は再利用性がないロジックになります。（拡張性なし！）<br>
どのdialogでもtitle、description, buttonは同じcssで同じ形で出力されてしまいます。

```react:Dialog.jsx:再利用性なし
import React from 'react'
import { useState } from 'react'

export default function Dialog(props) {
    const [isOpen, setIsOpen] = useState(false);
    return (
    <>
        <button
        onClick={()=> setIsOpen(true)}>Open</button>
        
        {isOpen && <div
        style={{
            position: "absolute",
            zIndex: 99,
            top: "50%",
            left: "50%",
            transform: "translate(-50%, -50%)",
            border: "1px solid black",
            padding: 24,
            backgroundColor: "white",
        }}
        >
            <p>Hello</p> 
            <h1>{props.title}</h1> 
            <h1>{props.description}</h1>
            <h1>{props.button}</h1>
            <button style={{backgroundColor:"red", color: "wthie"}} 
                    onClick={()=> setIsOpen(false)}>{props.button}</button>
            </div>
        }
    {isOpen && <div style={{
        position: "fixed",
        top: 0,
        left: 0,
        bottom: 0,
        right: 0,
        backgroundColor: "lightgray"
    }}/>}
    </>
    );
}
```
```react:ThankyouDialog.jsx
import React from 'react'
import Dialog from './Dialog'

export default function ThankyouDialog() {
  return (
    <Dialog 
    title="Thanks" 
    description="It is honor to meet you" 
    button="close"/>
  )
}
```
<br>
したは拡張性を持ったcompositionロジックになります。<br>
親のDialogコンポーネントがあり、その親のコンポーネントを使用して<br>
各自出力したいDialogの内容をcustomしDialogを出力することが可能です。

```react:Dialog.jsx:再利用性あり
import React from 'react'
import { useState } from 'react'

export default function Dialog(props) {
    const [isOpen, setIsOpen] = useState(false);
    return (
    <>
        <button
        onClick={()=> setIsOpen(true)}>Open</button>
        
        {isOpen && <div
        style={{
            position: "absolute",
            zIndex: 99,
            top: "50%",
            left: "50%",
            transform: "translate(-50%, -50%)",
            border: "1px solid black",
            padding: 24,
            backgroundColor: "white",
        }}
        >
            { typeof props.title === "string" ? (
            <h1>{props.title}</h1> 
            ) :  (props.title)} 
            
            { typeof props.description === "string" ? (
            <h1>{props.description}</h1> 
            ) :  (props.description)} 

            { typeof props.button === "string" ? (
            <button style={{backgroundColor:"red", color: "wthie"}}onClick={()=> setIsOpen(false)}>{props.button}</button>
            ) :  (
                <div onClick={()=>setIsOpen(false)}>
                {props.button}
                </div>
            )} 

            </div>
        }
    {isOpen && <div style={{
        position: "fixed",
        top: 0,
        left: 0,
        bottom: 0,
        right: 0,
        backgroundColor: "lightgray"
    }}/>}
    </>
    );
}
```
```react:ThankyouDialog.jsx
import React from 'react'
import Dialog from './Dialog'

export default function ThankyouDialog() {
  return (
    <Dialog 
        title={<h1 style={{color: `purple`}}>thanks</h1>}
        description="It is honor to meet you"
        button={<button style={{backgroundColor: "blue", color:"white"}}>close</button>}
        />
  )
}
```
```react:SorryDialog.jsx
import React from 'react'
import Dialog from './Dialog'

export default function SorryDialog() {
  return (
    <Dialog 
        title={<h1 style={{color: `red`}}>Sorry</h1>}
        description="Sorry My Fault!!"
        button={<button style={{backgroundColor: "red", color:"white"}}>close</button>}
        />
  )
}
```
したは結果！
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3097775/c093ce4b-8df6-1652-157e-6db4bbb0fc79.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3097775/8ca410f4-5eb7-e052-1379-edc7d3e4a1ac.png)