LoginSignup
2
4

More than 1 year has passed since last update.

Laravelのviewを、bladeからinertiaで部分的にReact化する

Posted at

個人でやってるサイトで、Reactの学習も兼ねて色々触ろうかと思うなかで、初めは別機能の部分を新規でNextJSで作ろうと思っていたのですが、一部機能だけとかだとログイン周りとかの処理が面倒で、そのままテンプレだけReactに移行できればと思って行いました。
というので、色々調べていたらLaravel->Reactはできそうというので、webpackを使うでもなく素bladeで作成されたプロジェクトの一部をReact化しました。

環境

Laravel 6だったところから、9にバージョンアップしたもの
なのでLaravelではViteがデフォルトになってますが、新規で作ってないのでvite.configとかもない状態でした

Nodeとyarnを入れる

この辺はメインの話ではないので雑に。下記から手に入れます。node18.14で実行しています。

ちなみに今回は関係ないですが、普段バージョン切り替えなどが必要なこともあるため私は n を利用しています。

yarnはこちら

Viteの導入

素のBladeと書いたので、Viteが動かない状態です。

各種パッケージを追加します。もしかしたらLaravel9ではもともとpackage.jsonに記載されているかもしれません。

yarn add -D vite laravel-vite-plugin @vitejs/plugin-react

設定ファイルはLaravel9から作っていれば初期からファイルがありそうですが、アップデートしたものなので自分で置きました。
またここで、 @vitejs/plugin-react を利用するため記載内容が少し異なります。

vite.config.js
import { defineConfig } from 'vite';
import laravel from 'laravel-vite-plugin';
import react from "@vitejs/plugin-react";

export default defineConfig({
    plugins: [
        laravel({
            input: ["resources/js/app.jsx"],
            refresh: true,
        }),
        react()
    ]
});

下のpackage.jsonも同様で、必要に応じて追記・上書きします。
webpackやそれ以外ですでに、devやbuildを使っているのであれば、別の名前をつけましょう。

package.json
  "scripts": {
    "dev": "vite",
    "build": "vite build",

  }

Inertiaの導入

LaravelのデータをReactにわたす場合は、Inertiaを使うようです

PHP側(サーバー側)

composer require inertiajs/inertia-laravel

Bladeは完全には消えず、 app.blade.php に下記のようなものを置く必要があるようです。

resources/views/app.blade.php
<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0" />
    @viteReactRefresh
    @vite('resources/js/app.jsx')
    @inertiaHead
  </head>
  <body>
    @inertia
  </body>
</html>

すでに app.blade.php を利用済みなら変更は可能で、上のsetupページと下記のリンクが参考になりそうです。
https://stackoverflow.com/questions/63926485/change-inertiajs-laravel-default-rootview

php artisan inertia:middleware

これで Http/Middleware/HandleInertiaRequests.php というミドルウェアのファイルが追加されます。多分コマンドを使うことでAppのnamespaceがちゃんと設定されるようです。
ちなみに、こいつを git add し忘れて本番で動かず困りましたw
このMiddlewareをKernelに追加

app/Http/Kernel.php
'web' => [
    // ...
    \App\Http\Middleware\HandleInertiaRequests::class,
],

\App の部分は独自のnamespaceを利用している場合は適宜変える必要があります。

JS側(クライアント側)

yarn add @inertiajs/react

ドキュメントには記載する内容は書いてあるが、どこに置くかが書いてないですが、上で設定値として記載した resource/js/app.jsx に置きます。
ドキュメントでは resource/js/app.js って書いてありますが、<App /> を使っているため、jsxである必要があります。

resource/js/app.jsx
import { createInertiaApp } from '@inertiajs/react'
import { createRoot } from 'react-dom/client'

createInertiaApp({
  resolve: name => {
    // TypeScriptなら.tsx
    const pages = import.meta.glob('./Pages/**/*.jsx', { eager: true })
    return pages[`./Pages/${name}.jsx`]
  },
  setup({ el, App, props }) {
    createRoot(el).render(<App {...props} />)
  },
})

実際にはTypeScriptにしたり、PostCSSとかSASSの導入、Storybookの導入などなどいろいろパッケージは必要だと思います。ここでは主題ではないので飛ばします。

参考:Jetsteram(かBreeze)

JetstreamでInertia等を導入することもできるようですが、新規のLaravelアプリケーションのみのようなので、今回はInertiaを直接入れています

PHP LaravelのControllerの書き換え

既存のページのview呼び出しを書き換えます。まだ作っていないディレクトリ構造なので適当に。

- return view('dir.template', []);
+ return Inertia::render('Dir/Template', []);

Reactの導入

Reactそのものは入れてない状態なので入れます

yarn add react react-dom

JSX(TSX)の追加

上記で指定したパスにJSXなりTSXを置きます

resources/js/Pages/Dir/Template.jsx
export default function Template () {
    return (
        <>
            <h1>タイトル</h1>
            <div>ほげほげ</div>
        </>
    )
}

値をテンプレートに渡す

Bladeと同様に、第二引数が渡されます。

return Inertia::render('Dir/Template', ['title' => 'test']);
resources/js/Pages/Dir/Template.jsx
export default function Template (props) {
    return (
        <>
            <h1>{props.title}</h1>
            <div>ほげほげ</div>
        </>
    )
}

TypeScript使ったほうが型を定められて便利かと思います

起動

yarn dev

アクセス

これでPHPサーバーの該当パスにアクセスすると表示されるはずです。
(自分の場合はlocalhost)

image.png

また、jsxのファイルを触るとブラウザ側に自動で反映されるはずです。めちゃ速い!
もちろん他のパスはこれまで通りBladeのVIEWに飛びます。

うまく出ないときは

  • WEBブラウザのデベロッパーツールからconsoleエラー確認
  • viteを立ち上げたコンソールの確認
  • PHP側のエラーの確認
  • サーバー側のエラーの確認

あたりの確認になると思います

Controllerの単体テスト

Controllerのactionの返り値は変わるので当然単体テストも変える必要があります。詳細は下記リンクで。

TypeScript対応

この辺はViteの話になってしまうため、雑に記載します。

yarn create vite

とやると初期のプロジェクトが作られます。このときに React TypeScript を選べば
image.png
image.png
tsconfig.json 等必要なファイルが作られるので、それを参考にするのが良いと思います。

おわりに

PHPのときは割とViewでHelper使ったり、ゴリゴリ処理入れたりしがちでしたが、JS(React)で処理する場合はロジックはちゃんとサーバー側に寄せて色々処理し、Viewでは表示に専念させるかたちにするのは大事だと感じました
という点で単にViewだけ切り替えてというのができない場合もありますが、部分的にReact化できるのは移行の面では非常に便利だと感じました。

2
4
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
4