【Laravel × React】LaravelでReactを使いたい

対象 LaravelにReact入れてみたい人

書いている人 プログラミング歴2年ほど

前提  Laravelプロジェクトを作成できる React少し触ったことがある

環境 PC:M1 mac Laravel: v9.0.1 React:v17.0.2

参考
日本語版ドキュメント:https://readouble.com/laravel/8.x/ja/sail.html(日本語版のドキュメントはまだver8)
海外版ドキュメントhttps://laravel.com/docs/9.x

先日Laravel9がリリースされた。Laravelは6の知識で止まっていたことと、最近LaravelのフロントにReactやVueを持っていきたいということがあって久しぶりにLaravelを触ってみた。今回はReactを入れていきます。
自分はLaravelもReactもどちらも独学の初学者レベルなので、同じようにやってみたい初心者向け。

今回はlaravel/uiというパッケージを使用してReactを使っていく。公式ではlaravel/uiは非推奨になっており、Laravel Breeze経由でReact等を入れてくれと書いてあったがそっちは難しすぎてギブした。Laravel Breeze経由でReactやVueを入れると、Inertia.jsというよくわからないものを学習する必要がありそう。

赤枠で囲っているところに、laravel/uiパッケージはlegacyパッケージであることが書かれている。
一応、Larvel9にも対応しているがゆくゆくは使えなくなってしまうのだろうか。
目次

フルスタックなのかAPIサーバーなのか

いきなり本題に入る前に、押さえておきたいことが一つ。
それは、Laravelの中にReactを組み込むのかLaravelとReactをそれぞれ独立して作ってあとで合体するのかどちらかということ。そもそも自分がこれを全く理解していなかった為に、色々な記事や動画を見ても今ひとつ要領を得られなかった。

見出しのフルスタックというのはLaravelの中にReactを組み込んでいくやり方で、今までBlade文に色々書いてきた部分をReactに変更するということ。今回紹介する方はこっち。
もう一つのAPIサーバーとして使うというのはLaravelとReactのプロジェクトを完全に分けてReactからアクセスした時にLaravelがjson形式でデータを返すAPIサーバーとして使うというもの。

Laravel公式にも記載がある通りどちらのやり方でもできる。どちらにせよLaravelの役割はDBとのやりとりになると思う。また、それぞれ独立させる場合はデプロイする時にそれぞれホスティング先を分ける必要はあるかも。

Laravelの公式より、2つの方法が紹介されている。

Laravel The Full Stack Framework

翻訳してみると、Bladeテンプレートを介してSPA(ReactやVueのようなアプリのこと)を表示させます的なことが書いてる

Laravel The API Backend

LaravelがJavaScriptシングルページアプリケーションまたはモバイルアプリケーションへのAPIバックエンドとしても機能する場ことが書かれている。

最近だとおそらくフロントエンドとバックエンドを切り分けることでチームで開発するのが楽になるからそれぞれ独立して作った方がよさそう。

さらに言えば、DBとしての役割はいまFirebaseとか様々なDBがサービスとして提供されているので、何か個人でサービスを作るならフロントとそっちを勉強すればよい気がするがLaravelを最初に触った身としてはある程度できるようになりたいので今回記事としてまとめる。

だいぶ前置きが長くなってしまったが、初心者の人は記事や動画を見る時にLaravelの中にReactを組み込んでいるのかそれぞれ別で作っているのかを意識すれば少しは見やすくなるのではないか。

Laravelプロジェクトを作成する

では、まずはLaravelプロジェクトを自分のローカルマシンに作成する。Laravel sailを使っても良いし、composer経由でもどちらでも。自分は触りだけなので、composerを使っていきます。

Laravel自体のインストール方法が分からなければどちらか参考にしてください。

ターミナルを準備して、好きなディレクトリにLaravelを作成しよう。ちなみにLaravel最新のバージョン9ではPHPのバージョンが8以上じゃないと動かないから、最新のLaravelを使用したい人はPHPのバージョンも上げておこう。

ターミナルで以下のコマンドを入力。example-appの部分は好きな名前で。また--prefer-distオプションをつけてもつけなくても。(これはいまだによくわかっていないがどうやらダウンロードする形式らしい。Githubからzipで落としているっぽい?)

composer create-project laravel/laravel example-app
laravel-reactという名前でLaravelプロジェクトを作成。
Laravel最新のv9.0.1がインストールされた。
お馴染みのLaravelの中身だ。
右下を見ると最新のLaravelが入っていることがわかる。

laravel/ui パッケージをインストール

Laravelプロジェクトを作成できたら次にlaravel/uiパッケージをインストールする。composerのパッケージとして登録されているのでcomposerコマンドを叩いて落としてくる。

上で作成したLaravelプロジェクトのフォルダ上でコマンドを入力。

composer require laravel/ui
こいつを落としてきている。
composer.jsonに"laravel/ui"パッケージが追加された。

laravel/uiパッケージのGitHub:https://github.com/laravel/ui

Reactをインストールする

laravel/uiパッケージをインストールしてきたら、次は以下のコマンドでReactのインストール準備をする。

php artisan ui react

認証機能も使いたいひとは--authオプションをつけるだけで認証機能も入れてくれるみたいだ。

php artisan ui react --auth

laravel/uiパッケージのGitHubを見てもわかる通り、reactだけではなく、vueやbootstrapでも入れられるみたいだ。

"laravel/ui"のGitHubにも記載されている。

今回認証機能はいらないでの、--authオプションは外しておく。

コマンドを入力すると以下のような文が返ってくるはずだ。これでReactをインストールする準備が整った。

成功したみたいだ。

この段階でpackage.jsonファイルを見てみると、新しくreactに関するものが追加されており、ついでにsassも書かれている。sassはcssを便利にしたようなやつだ。

Laravelだけの段階ではなかったreactやsassについてのパッケージが記入されている。

Reactをインストールする準備が整ったら、上にあるように、npm install && npm run dev コマンドを入力しよう。

これはnpm installnpm run dev&&でまとめて実行しているだけなのでもちろん一つずつ順番にやっても構わない。

※追加のパッケージを入れる必要があれば入れる

npm install && npm run devコマンドを実行すると自分の場合以下のように"追加のパッケージを入れてください"と指摘された。

指示通りにコマンドを入力しよう。

指示通り追加のパッケージをインストールしたら、以下のようになるはずだ。

これで最後にnpm run devを走らせるだけだ

最後にnpm run devコマンドを入力するとwebpack compiled successfullyと返ってきて準備完了だ。

これでLaravelでReactを使う準備が完了だ。

コマンドの入力に成功すると、resources/jsフォルダ以下にcomponentsフォルダが作成されており、その中にExample.jsコンポーネントが見える。これがReactのコンポーネントだ。

Example.jsなるものが表れた。
import React from 'react';
import ReactDOM from 'react-dom';

function Example() {
    return (
        <div className="container">
            <div className="row justify-content-center">
                <div className="col-md-8">
                    <div className="card">
                        <div className="card-header">Example Component</div>

                        <div className="card-body">I'm an example component!</div>
                    </div>
                </div>
            </div>
        </div>
    );
}

export default Example;

if (document.getElementById('example')) {
    ReactDOM.render(<Example />, document.getElementById('example'));
}

上記がExample.jsの中身だ。このコンポーネントを次は表示させていく。

welcome.blade.phpを書き換える

さて、いよいよこれでreactを使えるようなったが、もちろんこのままではまだ何も変わらない。php artisan serveでローカルサーバーを立ち上げてもいつものLaravelが出てくるだけだ。

上のExample.jsコンポーネントを表示させる為に、いくつか要素を書き換えていこう。まず最初はwelcome.blade.phpを変更する。

Laravelのweb.phpにはルーティングが書かれており、/にアクセスするとviewsフォルダの中のwelcome.blade.phpが返される。この中身が最初のLaravelのトップページに繋がるのでこれを書き換える。

web.phpの中でルーティングされている。
welcome.blade.phpの中身。こんなだったけ?

welcome.blade.phpを以下のように変更する。styleとbodyの中身を消しただけだ。

<!DOCTYPE html>
<html lang="{{ str_replace('_', '-', app()->getLocale()) }}">
    <head>
        <meta charset="utf-8">
        <meta name="viewport" content="width=device-width, initial-scale=1">

        <title>Laravel</title>

    </head>
    <body>
        ここにReactのコンポーネントを表示させたい
    </body>
</html>

新しくbodyの中に適当に文字を入力した。この中でReactのコンポーネントのExample.jsコンポーネントを表示させていく。

welcome.blade.phpの中身を書き換えてからアクセスした。すっきり。

このままだとbodyの中に文字を足しただけなので、Exampleコンポーネントにアクセスするためにbodyの中身に以下の2行を追加する。

<div id="example"></div>
<script src="{{ mix('js/app.js')}}"></script>

全体で見るとこんな感じ。

<!DOCTYPE html>
<html lang="{{ str_replace('_', '-', app()->getLocale()) }}">
    <head>
        <meta charset="utf-8">
        <meta name="viewport" content="width=device-width, initial-scale=1">

        <title>Laravel</title>

    </head>
    <body>
        <div id="example"></div>
        <script src="{{ mix('js/app.js')}}"></script>
    </body>
</html>

改めて、ブラウザで表示を確認してみるとExample.jsで書かれているものが表示されているはずだ。

スタイルは当たっていないがうまいこと表示された。

新たに書き加えたコードを見ていこう。

<div id="example"></div>の部分でid属性にexampleと書いている。これはExapmleコンポーネントの中でgetElementByIdでアクセスさせる為の記述だ。

if (document.getElementById('example')) {
    ReactDOM.render(<Example />, document.getElementById('example'));
}

getElementByIdメソッドでexampleを指定して、もしそれがあればExampleコンポーネントを表示してねという意味だ。

bodyの中身の2行目、<script src="{{ mix('js/app.js')}}"></script>部分でjsフォルダのapp.jsを読みこんでいる。mixメソッドはよくわからないがコンパイルする上で必要なのかな?

jsフォルダの中身のapp.jsを読み込んでいる。
/**
 * First we will load all of this project's JavaScript dependencies which
 * includes React and other helpers. It's a great starting point while
 * building robust, powerful web applications using React + Laravel.
 */

require('./bootstrap');

/**
 * Next, we will create a fresh React component instance and attach it to
 * the page. Then, you may begin adding components to this application
 * or customize the JavaScript scaffolding to fit your unique needs.
 */

require('./components/Example');

このapp.jsファイルの中で、Exampleコンポーネントを読み込んで表示している。

<div id="example"></div>
<script src="{{ mix('js/app.js')}}"></script>

上の2行のどちらが欠けても表示されないので気をつけよう。

次にstyleを当てていくために、welecome.blade.phpの中でcssを読み込む。

<!DOCTYPE html>
<html lang="{{ str_replace('_', '-', app()->getLocale()) }}">
    <head>
        <meta charset="utf-8">
        <meta name="viewport" content="width=device-width, initial-scale=1">

        <title>Laravel</title>
        //これを追加
        <link rel="stylesheet" href="{{mix('css/app.css')}}">
    </head>
    <body>
        <div id="example"></div>
        <script src="{{ mix('js/app.js')}}"></script>
    </body>
</html>

<link rel="stylesheet" href="{{mix('css/app.css')}}">の1行を追加してブラウザを確認するとbootstrapのスタイルがあたっていることがわかるはずだ。

bootstrapが当たった。

Exampleコンポーネントを書き換える

これでExampleコンポーネントが表示されるようになったので、試しにExampleコンポーネントの中身を書き換えてみよう。

import React from 'react';
import ReactDOM from 'react-dom';

function Example() {
    return (
        <div className="container">
            <div className="row justify-content-center">
                <div className="col-md-8">
                    <div className="card">
              //適当に変更する
                        <div className="card-header">テストです</div>

                        <div className="card-body">二郎が食べたいです</div>
                    </div>
                </div>
            </div>
        </div>
    );
}

export default Example;

if (document.getElementById('example')) {
    ReactDOM.render(<Example />, document.getElementById('example'));
}

書き換えた後に再度ブラウザをアクセスしても、変更が反映されていないはずだ。

なぜなら、ReactコンポーネントやVueコンポーネントを変更したら毎回npm run devコマンドを入力してビルドする必要があるためだ。

npm run devコマンドを入力した後にブラウザを確認すると変更が反映されているはずだ。

変更が反映された。

ただブラウザを更新しても変更されないので注意しよう。

laravel/uiのGitHubに「Vueコンポーネントを変更した際はnpm vun devと入力してください」と書かれている。Reactでも一緒だ。

どこにアクセスしてもwelcome.blade.phpを返すようにする

これでほとんど問題ないが、最後にweb.phpでルーティングを変更していこう。

ReactはSPAと言って、HTML一つでDOMだけを書き換えてページを変更していく。つまりこの場合は全ての起点にwelcome.blade.phpが返されるようにしたい。どのURLにアクセスしても、welcome.blade.phpにつながりそこで読み込んでいるExampleコンポーネントが返される。後はReactのコンポーネントをこの中で色々用意してページを作っていく感じだ。

今適当なパラメーターをくっつけると404が返されるはずだ。試しにパラメータをつけてアクセスしてみる。

パラメータをつけてアクセスすると...
404が返ってくる。

これをどのページにアクセスしても、welcome.blade.phpが返ってくるようにweb.phpを書き換えていこう。

Route::get('{any}', function () {
    return view('welcome');
})->where('any','.*');

詳しいことはわからないが、上のコードでどこのURLにアクセスしてもwelcome.blade.phpが返ってくるようになった。

まとめ

  • Laravelプロジェクトを作成し、laravel/uiパッケージを落とす。
  • laravel/uiパッケージからreactを落とし、npm install && npm run devコマンドを走らせる。(追加で必要なパッケージがあれば入れる。)
  • welcome.blade.phpとExampleコンポーネントを書き換える。
  • どこにアクセスしてもwelcome.blade.phpが返されるようにweb.phpを書き換える

こんな感じだろうか。知らないメソッドも中にあってだいぶ大雑把だがこれでLaravelの中でReactを使えるようになった。理解したら書き加えていきたい。また、次はLaravelとReactのプロジェクトをそれぞれわけて作成してみたい。少しでも参考になれば幸いです。

よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!
目次