Laravel(6.x) React+Material UIでGridデザイン
近頃Reactが流行っていますよね
LaravelでReactを使う方法はよく見かけるのですがじゃあ
Reactで具体的にどんなViewを見せてみるかまであまりなかったので
今回はMaterial UIのGridListを使った画像一覧画面を作ってみたいと思います
目次
この記事をすすめるとどうなる
以下のようなGridスタイルの画像一覧が作成できます

Reactを導入
まず、Laravelの表示ビューとしてReactを使えるようにします
composerでlaravel uiパッケージをインストールします
6系では以下コマンドでインストールします
composer require laravel/ui "^1.0" --dev
次にartisanコマンドを使ってuiをreactに設定します
php artisan ui react
$ php artisan ui react
React scaffolding installed successfully.
Please run "npm install && npm run dev" to compile your fresh scaffolding.
次に、npm install && npm run dev
を実行してコンパイルします
必要なnpmパッケージがインストールされ、reactで記述されたjsファイルが
コンパイルされます
npm install && npm run dev
コンパイルされると、 public/css、public/jsにコンパイル結果野ファイルが
出力されます
Material-UIを導入
Material-UIはすでにデザインも適用されたコンポーネントが多数入った
パッケージです
まずは以下コマンドでコアパッケージをインストールします
npm install @material-ui/core
ルーティング、コンパイルの設定をする
React、Material-UIを使えるようにしたので
新しいページを作成して、GridListを使った
一覧画面用のコンポーネントを作成します
routes/web.php
初期は、welcomeのみ入っている状態なので
以下を追加します
Route::get('/list', function () {
return view('list');
});
resources/views/list.blade.php
resources/views配下にroutesで指定したbladeファイルを作成します
ファイル名:list.blade.php
内容は以下です、シンプルなHTMLで
コンパイル出力するjsファイルのみ指定しておきます
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Grid Image List</title>
<link href="https://fonts.googleapis.com/css?family=Nunito:200,600" rel="stylesheet">
</head>
<body>
<div id="app"></div>
<script src="{{ asset('/js/list.js') }}"></script>
</body>
</html>
resources/js/list.js
コンパイル対象のjsファイルを作成します
中身は以下です
require('./bootstrap');
require('./components/List');
webpack.mix.js
ビルドツールのwebpackに、追加したresource/jsをコンパイルするように
指定します
2行目が追加したものです
mix.react('resources/js/app.js', 'public/js')
.react('resources/js/list.js', 'public/js')
.sass('resources/sass/app.scss', 'public/css');
コンポーネントを作成する
最後にMaterial-UIを使って画像一覧を表示するコンポーネントを
作成します
resources/js/components/List.jsx
resource/js/components配下にList.jsxを作成します
中身は以下です
import React from 'react'
import ReactDOM from 'react-dom'
import { makeStyles } from '@material-ui/core/styles'
import GridList from '@material-ui/core/GridList'
import GridListTile from '@material-ui/core/GridListTile'
import sample1 from '../../assets/images/sample1.jpg'
import sample2 from '../../assets/images/sample2.jpg'
import sample3 from '../../assets/images/sample3.jpg'
import sample4 from '../../assets/images/sample4.jpg'
import sample5 from '../../assets/images/sample5.jpg'
import sample6 from '../../assets/images/sample6.jpg'
import sample7 from '../../assets/images/sample7.jpg'
const sampleImageList = [
{ title: "サンプル1", img: sample1, cols: 2 },
{ title: "サンプル2", img: sample2 },
{ title: "サンプル3", img: sample3 },
{ title: "サンプル4", img: sample4, cols: 2 },
{ title: "サンプル5", img: sample5, cols: 2 },
{ title: "サンプル6", img: sample6 },
{ title: "サンプル7", img: sample7, cols: 2 },
]
const useStyles = makeStyles((theme) => ({
root: {
display: 'flex',
flexWrap: 'wrap',
justifyContent: 'space-around',
overflow: 'hidden',
},
gridList: {
width: 720,
height: '100%',
},
}));
export const List = () => {
const classes = useStyles();
return (
<div className={classes.root}>
<GridList cellHeight={280} className={classes.gridList} cols={3}>
{sampleImageList.map((tile) => (
<GridListTile key={tile.img} cols={tile.cols || 1}>
<img src={tile.img} alt={tile.title} />
</GridListTile>
))}
</GridList>
</div>
);
}
if (document.getElementById('app')) {
ReactDOM.render(<List />, document.getElementById('app'));
}
画像を配置する
上記List.jsxのファイルにサンプル画像を7つ定義しました
実ファイルがないとエラーとなるため適当な画像を用意してください
resourcesの直下に assets/images とディレクトリを作成し画像ファイルを
配置しましょう
importで呼び出された画像ファイルは、ビルド時にassets下のものを
publicに自動でコピーしてくれます
ビルドして画面を確認
npm run dev または npm run watch でビルドします
watchでビルドしておくほうが、ファイルの変更があれば再度自動で
ビルドしてくれるので楽になります
さらに別ターミナルでphp artisan serveでサーバを起動します
npm run watch
php artisan serve
http://localhost:8000/list にアクセスしてみましょう
以下のように画像一覧が表示されていれば成功です!

まとめ
LaravelでReactに簡単に切り替えられるのは便利ですよね
ただゼロからコンポーネントを用意して、デザインをあてて・・・というのは
結構たいへん
Material-UIなどのモダンなデザインで作られたコンポーネントパッケージ
を使うことでさくっと見栄えの良いページが作れます
他にも様々なコンポーネントを用意してくれてるのでぜひ試してみてください!