0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Laravel 12 blade + React その1

Last updated at Posted at 2025-09-28

はじめに独り言

 公式サイト含めネット上のReact入門解説情報は全くもって入門させる気が無い。なぜこんなにわかりにくい説明が多いのか謎。いや、それで理解できない自分がおかしいのか??

連携方法

 Laravel で React を使う方法はいくつかある。正直 React を使うならフレームワークは他のもの(NestJSとか良さそう)を使ったほうが React との相性は良いと思う。ここでは blade にReactコンポーネントを載せるという面倒な方法でやっている。ルーティングは Laravel で行い、画面には blade が返され、コンテンツが React という構成になるので Single Page Application ではない。でもSPAってそんなにこだわる部分かなぁ、と思っている。

コンポーネント

 機能を持った html タグのまとまりをコンポーネントと呼び、webページをコンポーネントを並べてデザインするという考え方。

 コンポーネントは javascript 関数として定義される。ファイル名、関数名は大文字で始めないと正常に動作しない。

Reactの構文
import React from 'react';

export default function SampleComponent() {        // コンポーネントは大文字で始める
    // 機能部分の記述

    return(
        // jsx(htmlタグみたいなやつ)の記述
    );
}

イベント処理の違い

 javascript は htmlタグ や文章をリアルタイムで書き換える言語として生まれ、発展してきた。そのためのライブラリも充実している。jQueryとか代表的。
 でも React はその歴史を全て塗り替えるような考え方をしている。
 たとえば、html に機能を実装させる方法として、以下のようなメソッドは使用しない。

javascriptでのイベント処理
document.element.addEventListener		// イベントを追加
document.element.innerHtml		        // 書き換え

 では React ではどうやって機能を実装するかというと、関数として定義する。

Reactのイベント処理
import react from react;

export default function SampleComponent() {
    
    // 機能部分の記述
    const eventHandle = () => {
        // 何か処理をする
    }

    return(            // return 内は div タグで囲む(最上位タグは必ずひとつ)
        <div>
            <button 
                onClick={eventHandle}        // イベント関数を指定
            >
                ボタン
            </button>
        </div>
    );
}

 イベントはタグの属性として指定する。次の章になるが最初は以下2つを攻略する。

  • クリックしたら何かが起こる系:onClick
  • 値が変わったら何かが起こる系:onChange

関数の書き方

 変数に無名関数を代入する書き方がよく使われる。

javascriptの関数
function MyFunc(x) { return x + 1; }

const Myfunc = (x) => { return x + 1; }        // 変数に無名関数を代入する記述方法

const MyFunc = x => x + 1;        // 引数が1つの場合カッコや return すら省略される

 上記3つは同じ。下2つの書き方をよく使う。慣れるまでは一見何をしているコードなのかわかりにくいよね。

Laravel 12 で React を使えるようにする

 対応の問題でnodejsversion 22 を、tailwindcssversion 3.4 をインストールする。 Laravel のインストールはcomposerコマンドで行う。laravel newコマンドを使ってインストールオプションのReactを選択するとInertia.jsを使ったSPA環境になるので、今回とは環境構成が異なる。以下のコマンドでインストールとアプリケーションを作成する。

composer create-project laravel/laravel app-name

 作成したアプリケーションのルートディレクトリへ移動して以下を実行する。

npm install react react-dom

 vite.config.jsに以下の設定があるか確認する。上記のコマンドを実行すれば、自動で記述されたような...。特に注意すべきポイントとして、app.jsではなく、app.jsxになっていることを確認する。

vite.config.js
    ... 他の部分省略 ...
    input ['resources/css/app.css', 'resources/js/app.jsx']

 resources/js配下のファイル名を確認し、app.jsではなくapp.jsxが存在するかを確認する。ファイル名がapp.jsになっている場合はリネームしてxを付け足す。

この環境の React の動作

 Controler が return view して blade が表示されると、最初にresources/js/app.jsxが走る。したがって、すべてのコンポーネントの呼び出しはapp.jsxで指定する。

resources/js/app.jsx
import ./bootstrap.js;            // 最初から書いてある行

import React from "react";                // 追記
import ReactDOM from "react-dom/client";  // 追記
import ./components/MyComponent;          // 自作したコンポーネントをインポート

const componentElement = document.getElementById('tag-id');    // blade のタグに記述されているID属性を取得して
if (componentElement) {                                        // 開いているbladeにタグidが存在したら
    const root = createRoot(componentElement); 
    root.render(<MyComponent />);                              // Reactコンポーネントを描画する
}

 で、この記述方法だとコンポーネントが増えてきたときにどの blade にアクセスしても全てのコンポーネントをインポートするという無駄な処理が発生する。SPAではないので関係ないコンポーネントは読み込む必要はない。無駄を発生させないために、該当するidタグが存在する場合にだけ必要なコンポーネントを読み込むようにする。

app.jsx
import ./bootstrap.js;

import react;
import react-dom;

const componentElement = document.getElementById('tag-id');
if (componentElement) {
    // idがある場合のみコンポーネントをインポート
    import('./components/MyComponent').then(({ default: MyComponent }) => {
        const root = createRoot(componentElement);
        root.render(<MyComponent />);
    });
}

 さらに、コンポーネントを増やすたびにこのコードを追記していくのはちょっとキツい。ということで、関数化する。

app.jsx
function mount(id, importer) {
    const el = document.getElementById(id);
    if (el) {
        importer().then(({ default: Cmp }) => {
            createRoot(el).render(<Cmp />);
        });
    }
}

mount('tag-id', () => import(./components/MyComponent));    // 1行で書けるようになった

 これでコンポーネントを追加したとき、1行の記述で設定できるようになった。
 この1行を追記する作業、忘れやすいので注意する。

コンポーネントの作成

 さっそくコンポーネントを作成する。
 resources/js/components/ExampleComponent.jsxとしてファイルを作成する。

resources/js/components/ExampleComponent.jsx
import React from 'react';

export default function ExampleComponent() {    // 大文字で始める
    return (
        <div>
            Example Component
        </div>
    );
}

 これは「Example Component」という文字列を表示するコンポーネント。機能は何もない。
 「return」で記述するHTMLタグっぽいやつはjsxと呼ばれている。
 コンポーネント記述のルールは以下の通り。

  • コンポーネント(定義関数)名は必ず大文字で始める
  • ファイル名も必ず大文字で始める
  • app.jsxでインポートできるようにコンポーネント関数はexportする
  • return では必ずひとつのタグを返すように記述する(divタグで囲めばよし)
  • return では必ず閉じタグが必要

 変数に関数を代入する記述でコンポーネントを定義する場合、必ず最後にexportする。

コンポーネントの別の書き方
const ExampleComponent = () => {      // 必ず大文字で始める
    コンポーネントの内容
}

export default ExampleComponent;      // const で定義した場合はこの記述が必要、忘れやすいんだよなぁ

 jsxは小文字で始まるものをhtmlタグ、大文字で始まるものをコンポーネントとして認識する。なのでコンポーネント名は大文字で始める必要がある。

 閉じタグが無いタグは以下のように記述する。

閉じタグがないタグの記述
<img  />
<input  />

// 閉じタグがないものには /> を記述する

 bladeファイル にはコンポーネントを埋め込む部分に以下を記述する。

bladeファイルへの記述
<div id="example"></div>

 app.jsxExampleComponentを呼び出す記述を忘れないように。

app.jsx
mount('example', () => import(./components/ExamleComponent));

 全て記述が終わったらもちろんコレを実行。

npm run build

次に続く。

0
0
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
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?