【Laravel+React】React側からAxiosでLaravelのAPI(MySQL)叩いてデータ取得

はじめに

以下記事を参考にLaravel+React試してみました◎

参考:初めてのLaravel6.xとReact入門

セットアップ

※Laravelプロジェクトが作成できていることが前提です。

laravel/uiをインストール(“1.x”を付けないと最新がインストールされ、Laravelのバージョン6と整合が取れない。)

$ composer require laravel/ui "1.x" --dev
$ php artisan ui react --auth
React scaffolding installed successfully.
$ npm install && npm run dev
$ npm run watch // 以降自動コンパイルしてくれる。

welcome.blade.php

<!doctype html>
<html lang="{{ str_replace('_', '-', app()->getLocale()) }}">

<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <!-- CSRF Token -->
    <meta name="csrf-token" content="{{ csrf_token() }}">
    <title>{{ config('app.name', 'Laravel') }}</title>
    <!-- Scripts -->
    <script src="{{ asset('js/app.js') }}" defer></script>
    <!-- Styles -->
    <link href="{{ asset('css/app.css') }}" rel="stylesheet">
</head>

<body>
    <div id="example"></div>
</body>
</html>

http://localhost:8000/にアクセス。

リファクタ

resources/js/app.js

require('./components/app');

resources/js/components/app.js

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

function App() {
  return (
    <>
      <h1>hello React!!</h1>
    </>
  );
}

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

index.blade.php

<!doctype html>
<html lang="{{ str_replace('_', '-', app()->getLocale()) }}">

<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <!-- CSRF Token -->
    <meta name="csrf-token" content="{{ csrf_token() }}">
    <title>{{ config('app.name', 'Laravel') }}</title>
    <!-- Scripts -->
    <script src="{{ asset('js/app.js') }}" defer></script>
    <!-- Styles -->
    <link href="{{ asset('css/app.css') }}" rel="stylesheet">
</head>

<body>
    <div id="app"></div>
</body>

</html>

Controller.php

※アクション追加

  public function index()
  {
      return view('index');
  }

web.php

Route::get('/', "Controller@index");

http://localhost:8000/にアクセス

React-routerを入れてみる

インストール

$ npm install react-router-dom

web.phpの編集

Route::get('/{any}', "Controller@index")->where('any','.*');

{any}を設定することで”/”(ルート)以下へのアクセスを行うとwelcome.blade.phpファイルが表示される設定を行っています。しかし{any}だけでは”/”(ルート)へのアクセスがあるとNot Foundエラーが発生します。そのため、where(‘any’,’.*’)も必要になります。

SwitchタグはURLのアクセスに対して一致する1つのコンポーネントのみ戻す役割。
※exactは完全一致の場合のみ表示。Linkタグはaタグに変換される(リロードなし)。

app.js

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

import Nav from "./Nav";
import About from "./About";
import User from "./User";
import Top from "./Top";

function App() {
    return (
        <Router>
            <Nav />
            <Switch>
                <Route path="/" exact component={Top} />
                <Route path="/about" component={About} />
                <Route path="/user" component={User} />
            </Switch>
        </Router>
    );
}

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

Nav.js

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

function Nav() {
    return (
        <nav>
            <ul className="nav">
                <Link to="/">
                    <li>Top</li>
                </Link>
                <Link to="/about">
                    <li>About</li>
                </Link>
                <Link to="/user">
                    <li>User</li>
                </Link>
            </ul>
        </nav>
    );
}

export default Nav;

Top.js

import React from 'react';

function Top() {
  return <h1>Topページ</h1>;
}

export default Top;

about.js

import React from 'react';

function About() {
  return <h1>Aboutページ</h1>;
}

export default About;

user.js

import React from 'react';

function User() {
  return <h1>Userページ</h1>;
}

export default User;

ビルド

$ npm run watch

ページ遷移できることを確認◎

DB活用

※XamppのMySQLを使います。

php.iniを編集

※僕の場合、事情がありXamppのPHPを使っていないため別途PHPの設定周りを修正

extension=mysqli
extension=pdo_mysql

参考:Laravelで”could not find driver”が出たときの対処法

config/database.phpを修正

// 'charset' => 'utf8mb4',
'charset' => 'utf8',
// 'collation' => 'utf8mb4_unicode_ci',
'collation' => 'utf8_unicode_ci',

参考:Laravel5.4以上、MySQL5.7.7未満 でusersテーブルのマイグレーションを実行すると Syntax error が発生する

実行

$ php artisan migrate
Migration table created successfully.
Migrating: 2014_10_12_000000_create_users_table
Migrated: 2014_10_12_000000_create_users_table (0.05 seconds)
Migrating: 2014_10_12_100000_create_password_resets_table
Migrated: 2014_10_12_100000_create_password_resets_table (0.05 seconds)
Migrating: 2019_08_19_000000_create_failed_jobs_table
Migrated: 2019_08_19_000000_create_failed_jobs_table (0.02 seconds)

ダミーデータ作成

$ php artisan make:seeder UsersTableSeeder
Seeder created successfully.

UsersTableSeeder.phpを編集

public function run()
{
    $users = factory(App\User::class, 50)->create();
}

DatabaseSeeder.phpの編集

public function run()
{
    $this->call(UsersTableSeeder::class);
}

実行

$ php artisan db:seed
Seeding: UsersTableSeeder
Seeded: UsersTableSeeder (0.21 seconds)
Database seeding completed successfully.

確認、いい感じです◎

データベースからAxiosで取得を行う

api.phpを編集

Route::get('/user',function (Request $request) {
  $users = App\User::all();
  return response()->json(['users' => $users]);
});

サーバーを再起動する。

http://localhost:8000/api/userにアクセス

user.jsを編集

import React, { useEffect, useState } from 'react';
import axios from 'axios';

function User() {
    const [users, setUsers] = useState([]);
    useEffect(() => {
        getUsers()
    },[])

    const getUsers = async () => {
        const response = await axios.get('/api/user');
        setUsers(response.data.users)
    }

    return (
        <div>
            <h1>Userページ</h1>
            <ul>
                {users.map((user) => <li key="{user.id}">{user.name}</li>)}
            </ul>
        </div>
    );
}

export default User;

http://localhost:8000/userにアクセスして取得を確認。

※記事ではユーザー詳細画面まで実装していたけどここまでで。

おわりに

ほぼ記事通りにやることでここまで実装できました。

LaravelとReactはそれぞれ学習していたのでコードも何となく理解できるのでここから応用して開発できそうです。

次はSwaggerと紐づけたい◎

コメントを残す