[簡単]React x LaravelのSPAで作るチュートリアル⑤(新規登録機能)

# SPAで作るタスク管理アプリのチュートリアル
今回は第⑤弾で新規登録機能をやっていくで
今回は第④弾でReactで一覧テーブル作成する部分をやっていくで
>
①[環境構築(Docker/Laravel/React.js/Material-UI)](https://qiita.com/morry_48/items/abd620f051fb4f36dcc2)
②[React側でルーティング設定](https://qiita.com/morry_48/items/b9287bbd4a7d4d312c65)
③[API取得してReactで一覧テーブル作成](https://qiita.com/morry_48/items/d0ee66eda70020c3f266)
④[API取得してReactで一覧表示](https://qiita.com/morry_48/items/1f7e7d74eee666e58379)
⑤新規登録機能
⑥[編集・削除機能](https://qiita.com/morry_48/items/261becf645a76eec13cf)

## 概要

### こんな感じで入力フォームから登録するとDBにデータが登録されて、一覧表示できる机上を実装していくで

![スクリーンショット 2021-05-05 10.31.40.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/378609/96f9847a-e054-6f00-e582-05eb6c527cba.png)


## まずバックエンドから
### Controllerの処理
`function create()`を作成する


```php:PostController.php

    public function index()
    {
        $posts = Post::all();
        return response()->json($posts, 200);
    }

    //index()の下に追記する
    public function create(Request $request)
    {
        $post = new Post;
        $post->name = $request->name;
        $post->content = $request->content;
        $post->save();
        return response()->json($post, 200);
    }
```
一般的なCRUDのうちのceate処理やね。
レスポンスにはjosn形式で登録したpostsを返してるで

### ルーティングを記載
/routes/api.phpに追記

```php:api.php
Route::group(['middleware' => 'api'], function(){
    Route::get('posts', 'App\Http\Controllers\Api\PostController@index');
    Route::post('post/create', 'App\Http\Controllers\Api\PostController@create'); //追記
});

```

`/api/post/create`で叩かれたときに先程定義した`create()`を叩くようにする
これはindex()と同じ要領で考えればOKやね



### PostManでテストしてみる
テストとしては
* POSTで`http://localhost/api/post/create`
* json形式で`name`と`content`を飛ばす


![スクリーンショット 2021-05-04 15.04.28.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/378609/9ced1184-a4f0-c53e-bb2b-a4fb974f02d8.png)


sendをクリックすると画像のようにresponseが返ってくればOKやで


![スクリーンショット 2021-05-04 15.05.22.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/378609/3034d5ed-2cca-c895-ef34-3cb74ad13fe8.png)


念のためにDBにデータが入ってるか確認しておこう

![スクリーンショット 2021-05-04 15.07.07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/378609/4a5300fd-c9f9-37c8-5d4a-ce952850da11.png)

`id=4`が追加されていることが分かる

次からフロント側を実装していくな

### コミットしとくで

```php
$ git add .
$ git commit -m"新規登録機能のバックエンド実装"
```

### 入力フォーム用のコンポーネント作成する
ここからはさっきテストした新規登録のAPIを叩くフロントエンドを実装してくで

```react:Home.js
import React, { useState, useEffect }　from 'react';
import { Button, Card } from '@material-ui/core';
import { makeStyles, createStyles } from '@material-ui/core/styles';
import MainTable from '../components/MainTable';
import axios from 'axios';
import PostFrom from '../components/PostFrom';　//新しく作るフォームのコンポーネントの呼び出し

```
jsxの「タスク管理」の直下にCardで囲ったPostFormの呼び出し

```react:Home.js

        <h1>タスク管理</h1>
        <Card className={classes.card}>  //追記
            <PostFrom  />  //追記
        </Card> //追記
        <Card className={classes.card}>
            {/* テーブル部分の定義 */}
            <MainTable headerList={headerList} rows={rows} />
        </Card>
    </div>

```

### 呼び出しの設定をした/components/PostFrom.jsを作成する
作成したファイルに下記を記載する

```react:PostForm.js
import React from 'react';
import { TextField, Button } from '@material-ui/core';
import { makeStyles, createStyles } from '@material-ui/core/styles';


const useStyles = makeStyles((theme) => createStyles({
    textArea: {
        marginRight: theme.spacing(2),
    },
}));



function PostFrom(props) {

    const classes = useStyles();



    return (
        <form>
            <TextField id="name" label="タスク名" variant="outlined" className={classes.textArea} name="name" />
            <TextField id="content" label="内容" variant="outlined" className={classes.textArea} name="content" />
            <Button color="primary" variant="contained" href="/" >登録</Button>
        </form>

    );
}

export default PostFrom;

```

### ビルドする

```php
$ make npm-dev

```

下記のように入力フォームが出てきたな

![スクリーンショット 2021-05-05 0.58.23.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/378609/186bc0f7-25b5-5004-d892-ccb97b2b6750.png)

入力しようとすると分かるけど、入力できへんようになっているな？
親コンポーネントから、データと入力値変更用のfunctionを渡してあげなあかんからそれを実装するで

### postsの下にformDataを設定する

```react:Home.js
    //postsの状態を管理する
    const [posts, setPosts] = useState([]);

    //フォームの入力値を管理するステートの定義
    const [formData, setFormData] = useState({name:'', content:''});　　　　//追記


```

### getPostData()の下にinputChange()を定義する

inputChange()は入力フォームの値変更用のfunctionやで


```react:Home.js
    //一覧情報を取得しステートpostsにセットする
    const getPostsData = () => {
        axios
            .get('/api/posts')
            .then(response => {
                setPosts(response.data);
            })
            .catch(() => {
                console.log('通信に失敗しました');
            });
    }

    //入力がされたら（都度）入力値を変更するためのfunction
    const inputChange = (e) => {
        const key = e.target.name;
        const value = e.target.value;
        formData[key] = value;
        let data = Object.assign({}, formData);
        setFormData(data);
    }


```

### PostFormコンポーネントに定義したステートとinputChangeを渡す


```react:Home.js
- <PostFrom />
+ <PostFrom data={formData} inputChange={inputChange} />

```

### PostFrom.js側で渡ってきたpropsを受ける
propsで受けてTextFieldに渡す

```react:PostForm.js

function PostFrom(props) {

    const classes = useStyles();

    const { data, inputChange } = props;//追記

    return (
        <form>
            <TextField id="name" label="タスク名" variant="outlined" className={classes.textArea} name="name" value={data.name} onChange={inputChange} />　//valueとonChange追記
            <TextField id="content" label="内容" variant="outlined" className={classes.textArea} name="content" value={data.content} onChange={inputChange} /> //valueとonChange追記
            <Button color="primary" variant="contained" href="/" onClick={btnFunc}>登録</Button>
        </form>

    );
```

### ビルド

```php
$ make npm-dev
```

![スクリーンショット 2021-05-05 1.14.40.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/378609/3b73c2e7-2948-3eec-59d6-39d6084329b0.png)

入力できるようになったな。

あとは登録ボタンが押されたときに入力されている値をjsonとして`http://localhost/api/post/create`を叩けばOKや

### cratePost()を実装して登録ボタンに渡す
inputChangeの定義部分の下辺りに`createPost`を定義する

```react:Home.js
    const createPost = async() => {
        //空だと弾く
        if(formData == ''){
            return;
        }
        //入力値を投げる
        await axios
            .post('/api/post/create', {
                name: formData.name,
                content: formData.content
            })
            .then((res) => {
                //戻り値をtodosにセット
                const tempPosts = posts
                tempPosts.push(res.data);
                setPosts(tempPosts)
                setFormData('');
            })
            .catch(error => {
                console.log(error);
            });
    }

```

PostFormコンポーネントに渡す

```react:Home.js
//btnFuncを渡す
<PostFrom data={formData} btnFunc={createPost} inputChange={inputChange} />

```
PostForm.jsで受ける

```react:PostFrom.js
   // btnFuncを追記
    const { data, inputChange, btnFunc} = props;

```
登録ボタンにonClickを渡す

```react:PostForm.js
<Button color="primary" variant="contained" href="/" onClick={btnFunc}>登録</Button> //onClickを追記

```
### ビルドする

```
$ make npm-dev
```
### データを登録してみる
タスク名='フロント君'
内容='新規データ'
で登録ボタンをクリックすると下記のようにデータが作られる

![スクリーンショット 2021-05-05 1.30.01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/378609/32fe739d-b7e6-b642-0ee2-f7a3b1363f17.png)



データが登録されて一覧にも表示された。

![スクリーンショット 2021-05-05 10.29.10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/378609/7dabea34-08eb-a9b6-58ed-87e8e0ca28d5.png)


```php
$ git add .
$ git commit -m"新規登録のフロントエンド実装"

```

次はいよいよ最後⑥やな登録したデータに対して編集機能と削除機能を実装していくで

ほな、LGTMよろしゅーです