LoginSignup
2
4

More than 3 years have passed since last update.

Reactタグの作り方

Last updated at Posted at 2020-01-14

はじめに

備忘録です。
Layoutタグを作ろうかな、と思ったときに以前のコードを見直す必要があったので、
整理とまとめておくために記述します。

もっといい方法があったら教えてください。
タイプミスあったらすみません。

code

Layout.jsxとUseLayout.jsxは同じ階層にあるものとします.
本当は分けた方がいいです...

Typescriptにする場合はChildrenはReactElementreactからimportして割り当ててあげると良い感じで行けます.
children: ReactElement<any>こんな感じで。

Layout.jsx

import React, { Fragment, cloneElement } from "react";

const Layout = props => {
  const { title, children } = props;
  return (
    <Fragment>
      <div>
        {title}
      </div>
      {cloneElement(children)}
    </Fragment>
  )
}

export default Layout;

UseLayout.jsx

import React from "react";
import Layout from "./Layout";

const UseLayout = () => (
  <Layout title="Layoutです">
    <div>
      componentを配置してね
      <button>ぼたんです</button>
    </div>
  </Layout>
)

Dialogを作りたい場合とかイベントを動的に変化させたい場合

material-uiの同じようなDialogを複数ページに適用させたい場合
ただし、イベントは変えたいよって場合
TypeScriptで書いていますが、JavaScriptにしたい場合はpropsを消して、
= ({children, title, ...}) =>= props =>にすればOK

Dialog.tsx

import React, { cloneElement, ReactElement } from "react";
import Dialog from "@material-ui/core/Dialog";
import Button from "@material-ui/core/Button";
import DialogActions from "@material-ui/core/DialogActions";
import DialogContent from "@material-ui/core/DialogContent";
import DialogContentText from "@material-ui/core/DialogContentText";
import DialogTitle from "@material-ui/core/DialogTitle";

type Props = {
  children: ReactElement<any>,
  title: string,
  description: string,
  disagree: string,
  agree: string,
  action?: Function | null,
}

const Dialog: React.FC<Props> = ({
  children,
  title,
  description,
  disagree,
  agree,
  action = null,
}) => {
  const [open, setOpen] = React.useState(false);
  return (
    <span>
      {cloneElement(children, {onClick: () => setOpen(true)})}
      <Dialog
        open={open}
        onClose={() => setOpen(false)}
      >
        <DialogTitle>{title}</DialogTitle>
        <DialogContent>
          <DialogContentText>
            {descriotion}
          <DialogContentText>
        </DialogContent>
        <DialogActions>
          <Button onClick={() => setOpen(false)}>
            {disagree}
          </Button>
          <Button onClick={() => {
            action !== null & action()
            setOpen(false);
          }}>
            {agree}
          </Button>
        </DialogActions>
      </Dialog>
    </span>
  )
}

ちょっと解説

上位から受け取ったchildrenはコンポーネントとしてDialog.tsxにもらえるので、

<Layout>
  <Button>Click!</Button>
</Layout>

のように使用できる.

タイトル, OKボタン, NGボタン, 説明は今回は必須の引数としているので

<Layout
  title="test"
  description="OK or NG?"
  disagree="NGボタン"
  agree="OKボタン"
  action={() => concole.log("OK or NGが押されました")}
>
  <Button>Click</Button>
</Layout>

となる.

そしてコンポーネント単位でアクションを設定したいので
actionに実行したい関数を渡してあげるとその関数を実行することが出来る.
react-reduxを使用する場合はactiondispatchを当てて使うこともできます.

2
4
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
4