Reactでdata-driven-formsを使ってみる

# [data driven forms](https://data-driven-forms.org/)

JSONで渡したデータをもとに、動的にフォームを生成するために、data driven formsを使う。
> Data Driven Forms converts JSON form definitions (schemas) into fully functional React forms with the provided set of features.
公式ページから引用

# 環境構築
- `create react app`を使ってReactの環境を作成

```
npx create-react-app data-driven-forms --template typescript
```
typescriptを使うため、`--template typescript`で作成

- 作成したファイルに移動する

```
cd data-driven-forms
```

# data driven formsの準備
- data driven formsを使うには`form renderer`のインストールと[使用するコンポーネントの選択](https://data-driven-forms.org/installation#mappers)が必要。ここで使用するコンポーネントは[Ant Design](https://ant.design/)  を選択。  
- `form renderer`のインストール

```
yarn add @data-driven-forms/react-form-renderer
```

- Ant Designをインストール

```
yarn add antd
```

```
yarn add @data-driven-forms/ant-component-mapper
```
# Ant Designのラジオボタンを表示する
## 1. `Radiobutton.tsx`を作成し、必要なモジュールをインポートする。

```Radiobutton.tsx
import React from 'react';
import FormRenderer from '@data-driven-forms/react-form-renderer/form-renderer';
import FormTemplate from '@data-driven-forms/ant-component-mapper/form-template';
import componentMapper from '@data-driven-forms/ant-component-mapper/component-mapper';
import 'antd/dist/antd.css'

import radiobutton from './schema'
```

## 2. ラジオボタンを表示させるための`schema`を定義する

```schema.ts
const radiobutton = {
    "fields": [
        {
            "component": "radio",
            "label": "Radio",
            "name": "radio",
            "options": [
                {
                    "label": "Dogs",
                    "value": "1"
                },
                {
                    "label": "Cats",
                    "value": "2"
                },
                {
                    "label": "Hamsters",
                    "value": "3"
                }
            ]
        }
    ]
};

export default radiobutton
```

## 3.`Radiobutton.tsx`のreturnに描画処理を追加  

```Radiobutton.tsx
export const Radiobutton = () => {
    return (
        <div style={{ margin: 24 }}>
            <FormRenderer
                schema={radiobutton}
                FormTemplate={FormTemplate}
                componentMapper={componentMapper}
                onSubmit={console.log}
            />
        </div>
    )
}
```
**onSubmit={console.log}だとonSubmitが実行されない**

→ `onSubmit={value => console.log(value)}`とするとonSubmitが実行されるようになった
([REACT FINAL FORM](https://final-form.org/docs/react-final-form/faq)のFAQページ中盤のVia Closure部分)

```Radiobutton.tsx
export const Radiobutton = () => {
    return (
        <div style={{ margin: 24 }}>
            <FormRenderer
                schema={radiobutton}
                FormTemplate={FormTemplate}
                componentMapper={componentMapper}
                onSubmit={value => console.log(value)}
            />
        </div>
    )
}
```

同じものをクラスで書くと下記のようになります。

```Radiobutton.tsx
class Radiobutton extends Component {
    render() {
        return (
            <div style={{ margin: 24 }}>
                <FormRenderer
                    schema={radiobutton}
                    FormTemplate={FormTemplate}
                    componentMapper={componentMapper}
                    onSubmit={console.log}
                />
            </div>
        );
    }
}

export default Radiobutton;
```

## 4. App.tsxにRadiobuttonコンポーネントをインポートして表示する

```App.tsx
import { Radiobutton } from './components/Radiobutton/Radiobutton'

function App() {
  return (
    <div className="App">
      <Radiobutton />
    </div>
  );
}

export default App;
```
ここまで完了後、実行すると下記のようになりました。

![2.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/742615/7462269d-8442-8426-8943-36dcee42dc4a.gif)

## 5．schemaの読み込みをJSONから行う
- `schema.ts`で定義しているschemaをJSONで読み込むように変更する  
src直下にschemaフォルダを作成。そこに`radioButton.json`ファイルを作成。
ファイルの中身は`schema.ts`と同じです。

```radioButton.json
{
    "fields": [
        {
            "component": "radio",
            "label": "Radio",
            "name": "radio",
            "options": [
                {
                    "label": "Dogs",
                    "value": "1"
                },
                {
                    "label": "Cats",
                    "value": "2"
                },
                {
                    "label": "Hamsters",
                    "value": "3"
                }
            ]
        }
    ]
}
```
- 作成したJSONを`Radiobutton.tsx`でインポートする  

```Radiobutton.tsx
import radiobutton from '../../schemas/radioButton.json'
```
radiobuttonとしてインポートし、schemaに渡す。

### Data-Driven-FormsでAnt Designのラジオボタンの表示ができました。
他のcssフレームワークを使う場合も基本的な流れは同じです。