第11回 Laravel10 環境構築メモ(Laravel+Typescript+React+inertiaで一覧表示してみる)

はじめに

前回、データの作成が完了したので、今回はとりあず画面に作成したデータを一覧表示したいと思います。データを取得して、inertiaを使って、Reactに渡すというシンプルながらの基本です。ちなみに、さっと調べたんですが、React+Typescript+inertiaの組み合わせで開発してる人って少ないんですかね?あんまり良い情報が見つからない・・・。

Laravel側に必要なモノを作っていく

まず、Controllerを作ります。オプションの--resourceは、リソースコントローラ(簡単に言うとCRUDに必要なメソッドをControllerに一緒に作ってくれる)を作るときに使いますが、付けなくても良いです。

 php artisan make:controller GreetingController --resource

   INFO  Controller [app/Http/Controllers/GreetingController.php] created successfully. 

↓のファイルが作成されます。(あとでいじります)

  • app/Http/Controllers/GreetingController.php

<?php

namespace App\Http\Controllers;

use App\Http\Resources\GreetingResource;
use App\Models\Greeting;
use Illuminate\Http\Request;
use Inertia\Inertia;

class GreetingController extends Controller
{
    /**
     * Display a listing of the resource.
     */
    public function index()
    {
    }

/** 省略 **/

}

次にResourceとResource collectionを作成します。

php artisan make:resource GreetingResource

   INFO  Resource [app/Http/Resources/GreetingResource.php] created successfully.  
make:resource Greeting --collection

   INFO  Resource collection [app/Http/Resources/Greeting.php] created successfully. 

↓のファイルがそれぞれ作成されます。(今回は、いじりません)昔のLaravelでは提供されてなかったと思うのですが、これらが何に使われるかというとAPI作るときにJSONでいい感じに返してくれる奴くらいの理解度でい一旦、使ってみます。

APIを構築する場合、Eloquentモデルと実際にアプリケーションのユーザーへ返すJSONレスポンスの間に変換レイヤーが必要になるでしょう。たとえば、ユーザーのサブセットに対して特定の属性を表示し、他のユーザーには表示したくない場合や、モデルのJSON表現に常に特定のリレーションを含めたい場合などです。Eloquentのリソースクラスを使用すると、モデルとモデルコレクションを表現力豊かかつ簡単にJSONに変換できます。
もちろん、toJsonメソッドを使用してEloquentモデルまたはコレクションをJSONへいつでも変換できます。ただし、Eloquentリソースは、モデルのJSONシリアル化とそれらの関係をよりきめ細かく堅牢に制御します。

https://readouble.com/laravel/10.x/ja/eloquent-resources.html
  • app/Http/Resources/Greeting.php

<?php

namespace App\Http\Resources;

use Illuminate\Http\Request;
use Illuminate\Http\Resources\Json\ResourceCollection;

class Greeting extends ResourceCollection
{
    /**
     * Transform the resource collection into an array.
     *
     * @return array<int|string, mixed>
     */
    public function toArray(Request $request): array
    {
        return parent::toArray($request);
    }
}
  • app/Http/Resources/GreetingResource.php

<?php

namespace App\Http\Resources;

use Illuminate\Http\Request;
use Illuminate\Http\Resources\Json\JsonResource;

class GreetingResource extends JsonResource
{
    /**
     * Transform the resource into an array.
     *
     * @return array<string, mixed>
     */
    public function toArray(Request $request): array
    {
        return parent::toArray($request);
    }
}

必要なファイルが用意できたので、一旦、データ取得が行われるか試してみます。まずは、Controllerを修正してjsonで取得したデータを返却してみます。

  • app/Http/Controllers/GreetingController.php

<?php

namespace App\Http\Controllers;

use App\Http\Resources\GreetingResource;
use App\Models\Greeting;
use Illuminate\Http\Request;

class GreetingController extends Controller
{
    /**
     * Display a listing of the resource.
     */
    public function index()
    {
        return GreetingResource::collection(Greeting::all());
    }

/** 省略 **/

}

次にrouteに上記のcontrollerを登録します。

  • routes/web.php

Route::resource('greetings', GreetingController::class);

http://localhost/greetingsにアクセスしてみると↓の様にjson形式でデータが表示されました。

{"data":[
 {"id":1,
  "country":"Botswana",
  "message":"Dolorem facere a ex ut temporibus eius. Voluptates sed aut sed natus. Expedita id aliquid soluta sed rerum quaerat.",
  "created_at":"2023-12-02T14:31:24.000000Z",
  "updated_at":"2023-12-02T14:31:24.000000Z"
 },
{"id":2,"country":"Cook Islands",
  "message":"Reiciendis qui blanditiis ipsam error. Voluptas nisi maxime sapiente expedita consequuntur ducimus. Vel error eius voluptatibus aut.",
  "created_at":"2023-12-02T14:31:24.000000Z",
  "updated_at":"2023-12-02T14:31:24.000000Z"
 },

 /** 省略 **/
]}

Reactでデータを表示してみる

ここまでは素振りです。今日の目的はここからです。まず、最初にcontrollerを修正して、inertiaでReactのcomponentにデータを渡すようにします。

  • app/Http/Controllers/GreetingController.php

<?php

namespace App\Http\Controllers;

use App\Http\Resources\GreetingResource;
use App\Models\Greeting;
use Illuminate\Http\Request;
use Inertia\Inertia;

class GreetingController extends Controller
{
    /**
     * Display a listing of the resource.
     */
    public function index()
    {
        return Inertia::render('Greeting/index', [
            'greetings' => GreetingResource::collection(Greeting::all()),
            'title' => 'Greetings'
        ]);
    }

/** 省略 **/

}

次に一覧を表示するReactのcomponentを作成します。

  • resources/js/Pages/Greeting/index.tsx

import { Head } from '@inertiajs/react'
import { type FC } from 'react'

const Index: FC = ({ greetings, title }) => {
  return (
    <>
      <Head title={title} />
      { greetings.data.map((greeting) => (
        <div key={greeting.id}>
          <h2>#{greeting.id} - {greeting.country}</h2>
          <p>{greeting.message}</p>
        </div>
      )) }
    </>)
}
export default Index

あんまり、まだ良く理解できていないのですが、componentの引数にcontrollerでセットした値を渡せる模様。

http://localhost/greetingsにアクセスしてみると↓の様にページが表示されました。

http://localhost/greetings

参考にしたサイト


いいなと思ったら応援しよう!