Inertia.jsの基本的な書き方を流れで紹介します
いつもご利用ありがとうございます。
この記事には広告が掲載されており、その広告費によって運営しています。
Inertia.js を使った Laravel での開発における、基本的な書き方についてまとめました。
はじめに
今回やることは、網羅的に「こういう時、こう書く」という備忘録的なものとなります。
Laravel を初めて触った人にも順を追ってやればページが作れるような記事を目指しています。
- Laravel 11
- 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'); //新規作成する
});
コントローラー
コントローラーの作成
まず、コマンドでコントローラーを作成します。
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.php
にname('post.store')
と書いた部分になり、エンドポイント(URL)が入ります。
const createPost = e => {
e.preventDefault() // デフォルトのフォーム送信を防ぐ
//略
}
この部分は必須でした。これがないと、デフォルトのフォーム送信が動いてしまい、関数でフォームを動かす今回の書き方とコンフリクトしてしまいました。
ブラウザでタイトルと内容を入力して投稿ボタンを押して、データベースに追加されていれば OK です。
おわりに
以上、Inertia を使った基本的な書き方をまとめてみました。
確かに、Laravel でフロントエンドを書く場合、だいぶ楽になったんじゃないかと思います。
フロントエンドとバックエンドを分けて開発するほどではない小規模なサービスであればかなり使えるんじゃないかなと思います。
デザイン決まってる小さいサービスを開発運用して欲しい方からのお問い合わせお待ちしております!
誰かの参考になれば幸いです。