独学エンジニアのメモ帳

得た知識のアウトプットとか日常のメモとか。ゆるくやる。

Laravel8 + ReactのSPA環境構築

前提条件

・Laravel8のプロジェクトを作成し、初期画面表示まで完了している

環境構築した時の記事 nochio12.hatenablog.com

導入

Laravel8から公式にサポートされたJetstream+inertiaも気になりましたが、
どうもJetstreamはVueしか対応していないようなので、今回はスルーします。
Introduction | Laravel Jetstream

というわけで、Reactの導入手順はLaravel6辺りからと同じ手順です。

Reactのインストール

uiパッケージのインストール

$ composer require laravel/ui

Reactの導入

$ php artisan ui react --auth

...

Please run "npm install && npm run dev" to compile your fresh scaffolding.

ビルド

$ npm install
$ npm run dev

Reactの準備は一旦OK

Laravelのルーティングの設定

前の手順でbladeがいくつかできますが
SPAでは不要になるので消していきます。

また、ルーティングもReact側でやるので修正します。

削除前
resources
┗ views
┣ auth (削除)
┣ layouts - app.blade.php (views直下に移動)
┣ home.blade.php(削除)
┗ welcome.blade.php(削除)

削除後
resources
┗ views
┗ app.blade.php

app.blade.phpを修正

<body>
    <!-- divの中身を削除 -->
    <div id="app">
    </div>
</body>

resources/js/components/Example.js

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

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

ここまでできたらビルド

$ npm run dev

web.phpを修正して、
どんなURLでもapp.blade.phpを返すようにします。

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

ページを更新し、
ExampeComponentが表示されればOK

f:id:nochio12:20201002231835p:plain

Reactの初期設定

app.jsに初期設定を記述
app.js

require('./bootstrap');

import React from 'react';
import ReactDOM from 'react-dom';
import Example from './components/Example';


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

Exampleから描画関数を削除 Example.js

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

Reactのルーティング設定

ルーティングライブラリをインストール

$ npm install react-router-dom

jsディレクトリに
NavBar.js
Home.js
About.js
の3つを作成

NavBar.js

import React from 'react';
import { Link } from 'react-router-dom';

const NavBar = () => {
    return (
        <div>
            <Link to="/">Home</Link>
            <Link to="/about">About</Link>
        </div>
    );
}

export default NavBar;

Home.js

import React from 'react';

const Home = () => {
    return (
        <div>
            Home
        </div>
    );
}

export default Home;

About.js

import React from 'react';

const About = () => {
    return (
        <div>
            About
        </div>
    );
}

export default About;

app.jsを変更

import React from "react";
import ReactDOM from "react-dom";
import { BrowserRouter, Route } from "react-router-dom";

import NavBar from "./NavBar";
import Home from "./Home";
import About from "./About";

const App = () => {
    return (
        <BrowserRouter>
            <NavBar />
            <Route path="/about" component={About} />
            <Route exact path="/" component={Home} />
        </BrowserRouter>
    );
};

if (document.getElementById("app")) {
    ReactDOM.render(<App />, document.getElementById("app"));
}

ルーターを使用する範囲をBrowserRouterで囲む必要があります。 Routeで、NavBar内のLinkのパスに対応するコンポーネントをセットしています。

$ npm run dev

して確認

f:id:nochio12:20201003001005g:plain

画面とURLが切り替わるのが確認できればOK 後はゴリゴリ開発していくだけです。