ホーム > Laravel > Inertia.jsの基本的な書き方を流れで紹介します
Laravel

Inertia.jsの基本的な書き方を流れで紹介します

いつもご利用ありがとうございます。
この記事には広告が掲載されており、その広告費によって運営しています。

Inertia.js を使った Laravel での開発における、基本的な書き方についてまとめました。

はじめに

今回やることは、網羅的に「こういう時、こう書く」という備忘録的なものとなります。

Laravel を初めて触った人にも順を追ってやればページが作れるような記事を目指しています。

  1. Laravel 11
  2. Breeze で Inertia.js React を選択

Laravel の Breeze とは?設定方法やできることをまとめました

この記事では、posts というテーブルの一覧ページを表示したり、新規作成をつけたりしてみようと思います。

データベースの作成

postsテーブルを作成する

title,contentの2つのシンプルなカラムだけ用意します。

php artisan make:migration create_posts_table

コマンドを打つと、database/migrations/2024_11_26_060317_create_posts_table.phpができたので開きます。

マイグレーションファイルの編集

以下のようにファイルを変更します。

    public function up(): void
    {
        Schema::create('posts', function (Blueprint $table) {
            $table->id();
            $table->string('title'); //追加
            $table->string('content'); //追加
            $table->timestamps();
        });
    }

コマンドでデータベースの変更を反映

php artisan migrate

以上でpostsテーブルが作成されていれば OK です。

Post モデルの作成

最後に、コマンドで Post モデルを作成しておきましょう。

php artisan make:model Post

app\Models\Post.phpが作成されたら OK です。

ルーティング

ルーティングの書き方は、通常と変わりません。

今回、一覧ページは誰でもみられるページ、新規作成ページは認証済みのユーザーのみ開けるページにしたいと思います。

routes/web.php

Route::get('/posts',[PostController::class, 'index'])->name('post.index'); //一覧を表示するページ

Route::middleware('auth')->group(function () {
    //略
    Route::get('/post/create',[PostController::class, 'create'])->name('post.create'); //新規作成ページ
    Route::post('/post',[PostController::class, 'store'])->name('post.store'); //新規作成する
});

Laravel のルーティングの基本的な書き方

コントローラー

コントローラーの作成

まず、コマンドでコントローラーを作成します。

php artisan make:controller PostController

コマンドを打つと、app/Http/Controllers/PostController.phpが作成されるので、開きます。

コントローラーの編集

<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use Inertia\Inertia;

use Illuminate\Http\RedirectResponse;
use Inertia\Response;
use App\Models\Post;

class PostController extends Controller
{
    //一覧ページ
    public function index(): Response
    {
        $posts = Post::orderBy('id','desc')->get();
        return Inertia::render('Post/Index',compact('posts'));
    }

    //新規作成ページ
    public function create(): Response
    {
        return Inertia::render('Post/Create');
    }

    //新規作成する
    public function store(Request $request): RedirectResponse
    {
        $post = new Post;
        $post->title = $request->title;
        $post->content = $request->content;
        $post->save();
        return redirect()->route('post.index');
    }
}

表示

表示の部分、とくにフォームの書き方については別途詳しい記事があるので、不十分だと感じたら確認してみてください。

【Laravel】Inertia のフォームの使い方を簡潔にまとめる

一覧ページ

ブラウザで表示しておく

http://localhost/postsにアクセスするなどしてブラウザで表示します。

最初はエラーになっていると思います。

表示のファイルを作成

resources/js/Pages/Post/Index.jsを作成し、一覧を表示するだけのページを作ります。

コントローラーのreturnのところで書いたパスは、resources/js/Pages/を基準としたパスです。

resources/js/Pages/Post/Index.jsの編集

import { Head, Link } from "@inertiajs/react"

export default function Index({ posts }) {
  const title = "投稿一覧"
  return (
    <>
      <Head title={title} />

      <div className="w-4/5 mx-auto py-12">
        <h1>{title}</h1>
        <table className="table-auto">
          <thead>
            <tr>
              <th>タイトル</th>
              <th>内容</th>
            </tr>
          </thead>
          <tbody>
            {posts.map(post => {
              return (
                <tr>
                  <td>{post.title}</td>
                  <td>{post.content}</td>
                </tr>
              )
            })}
          </tbody>
        </table>
      </div>
    </>
  )
}

変数を使う方法

コントローラーから送られてきた変数の使う方法は、

export default function Index({ posts }) {

このpostsの部分が使いたい変数で、Propsに書いてあげるだけで使うことができます。

複数の場合、

export default function Index({ posts,hoge }) {

と書けば OK です。

新規作成ページ

同様に新規作成ページを作ります。

ブラウザで表示する

ログインしていないと表示できないページなので、ログインして

http://localhost/post/createにアクセスするなどしてブラウザで表示します。

表示のファイルの作成

resources/js/Pages/Post/Create.jsを作成し、一覧を表示するだけのページを作ります。

表示のファイルの編集

import { Head, Link, useForm } from "@inertiajs/react"

export default function Edit() {
  //使えるプロパティ{data,setData,errors,post,put,reset,processing,recentlySuccessful}など
  const form = useForm({
    title: "",
    content: "",
  })

  const createPost = e => {
    e.preventDefault() // デフォルトのフォーム送信を防ぐ
    form.post(route("post.store"), {
      preserveScroll: true,
      onSuccess: () => reset(), //formのリセット
      onError: errors => {
        //エラー時の処理を書く
      },
    })
  }

  const title = "投稿の新規作成"
  return (
    <>
      <Head title={title} />

      <div className="w-4/5 mx-auto py-12">
        <h1>{title}</h1>
        <form onSubmit={createPost}>
          <div>
            <div>
              <input
                value={form.data.title}
                onChange={e => form.setData("title", e.target.value)}
                placeholder="タイトル"
              />
            </div>
            <div>
              <textarea
                value={form.data.content}
                onChange={e => form.setData("content", e.target.value)}
                placeholder="内容"
              ></textarea>
            </div>
            <button>投稿</button>
          </div>
        </form>
      </div>
    </>
  )
}

送信したいタイトルなどの変数は、useForm で管理する

import { Head, Link, useForm } from "@inertiajs/react"
//略
const form = useForm({
  title: "",
  content: "",
})

今回送信したいのがtitle,contentの2項目だったので、こうなります。

title,content を表示で使う

呼び出し自体は、form.data.titleと書けば表示できます。

今回は、<input/><textarea></textarea>の value で使いたいので、

<input
  value={form.data.title}
  onChange={e => form.setData("title", e.target.value)}
  placeholder="タイトル"
/>

となっています。

送信処理

<button>を押すと、submit が走る。

<form onSubmit={createPost}>

で次の関数が動く。

const createPost = e => {
  e.preventDefault() // デフォルトのフォーム送信を防ぐ
  form.post(route("post.store"), {
    preserveScroll: true,
    onSuccess: () => reset(), //formのリセット
    onError: errors => {
      //エラー時の処理を書く
    },
  })
}

form.postで、最初に定義したtitle,contentといったものをまとめて POST してくれます。

route("post.store")は、routes/web.phpname('post.store')と書いた部分になり、エンドポイント(URL)が入ります。

const createPost = e => {
  e.preventDefault() // デフォルトのフォーム送信を防ぐ
  //略
}

この部分は必須でした。これがないと、デフォルトのフォーム送信が動いてしまい、関数でフォームを動かす今回の書き方とコンフリクトしてしまいました。

ブラウザでタイトルと内容を入力して投稿ボタンを押して、データベースに追加されていれば OK です。

おわりに

以上、Inertia を使った基本的な書き方をまとめてみました。

確かに、Laravel でフロントエンドを書く場合、だいぶ楽になったんじゃないかと思います。

フロントエンドとバックエンドを分けて開発するほどではない小規模なサービスであればかなり使えるんじゃないかなと思います。

デザイン決まってる小さいサービスを開発運用して欲しい方からのお問い合わせお待ちしております!

誰かの参考になれば幸いです。

フィードバックのお願い
この記事のフィードバックがありましたらYoutubeの適当な動画にコメントしていただいたり、お問い合わせからご連絡ください。