この記事では、Laravelに一部Reactを導入している際にLaravelでの変数をReactに渡す方法を紹介します。
Inertia.jsを使っていると、Controllerから簡単に値を渡すことができますが、Reactを部分的に導入しているとLaravel側の変数をReact側に渡すには一工夫必要です。
方法はいくつかありますが、私が試した方法が参考になれば幸いです。
この記事を読むメリット
- 部分的に導入しているReactにLaravelから値を渡す方法が分かる
前提:Laravelに一部Reactを導入している
今回は、Laravelに一部Reactを導入している前提で進めていきます。
導入方法を知りたい方は、以下記事を参考にしてみてください。
webpackかviteかで設定方法に若干違いがあります。
ご自身がお使いの環境に合わせて参考にしてみてください。
app.jsは以下のように設定してあります。
import React from "react";
import { createRoot } from "react-dom/client";
import ExampleComponent from "./components/ExampleComponent";
import AnotherComponent from "./components/AnotherComponent";
// コンポーネントと対応するDOM要素のマッピング
const components = [
{ id: "example", component: ExampleComponent },
{ id: "another", component: AnotherComponent },
// 新しいコンポーネントが必要な場合は追加していく
];
components.forEach(({ id, component }) => {
const container = document.getElementById(id);
if (container) {
const root = createRoot(container);
root.render(React.createElement(component));
}
});
上記の記事で詳しく解説していますが、以下のような仕組みでReactを動作させています。
- Reactコンポーネントとそれに対応するDOM要素のidをマッピングする
- マッピングした配列をループして対象のDOMが存在する場合は、対応するReactコンポーネントをレンダリングする
このような設定がしてある前提で進めていきます。
エンジニアにおすすめ書籍
エンジニアになりたて、これから勉強を深めていきたいという方におすすめの書籍はこちら!
Laravel側の変数をReactに渡す方法
ここから実際にLaravel側の変数をReactに渡す方法を紹介していきます。
まずは手順を簡単に整理します。
- Controller側で変数を配列で渡す
- Blade内でLaravelから渡されたデータをデータ属性として埋め込む
- app.js内でコンポーネントにデータを渡す
- 各コンポーネントでpropsを受け取る
それでは1つずつ解説していきます。
Controller側で変数を配列で渡す
まずはLaravelのController側で変数を渡します。
public function dashboard()
{
$reactData = [
'message' => 'Hello, React!',
'user' => [
'name' => 'Sample User',
'email' => 'test@test.com',
]
];
return view('dashboard')
->with('reactData', $reactData);
}
blade側で個々の変数を配列に入れても良いですが、今回はController側で配列にしてbladeに渡しています。
ここはLaravel側のことなので細かい説明は省きます。
Blade内でLaravelから渡されたデータをデータ属性として埋め込む
続いてはblade側でContollerから渡したデータを埋め込みます。
<x-app-layout>
<x-slot name="header">
<h2 class="font-semibold text-xl text-gray-800 leading-tight">
{{ __('Dashboard') }}
</h2>
</x-slot>
<div class="py-12">
<div class="max-w-7xl mx-auto sm:px-6 lg:px-8">
<div class="bg-white overflow-hidden shadow-sm sm:rounded-lg">
<div class="p-6 bg-white border-b border-gray-200">
{{-- Laravelから渡されたデータをデータ属性として埋め込む --}}
<div id="example" data-props='@json($reactData)'></div>
</div>
</div>
</div>
</div>
</x-app-layout>
ポイントは「<div id=”example” data-props=’@json($reactData)’></div>」の部分です。
id要素が「example」の要素でExampleComponentがレンダリングされるので、その要素に渡したいデータを「data-props」として渡します。
js側にデータを送る際はJSON形式にする必要があるので「@json($reactData)」にします。
Laravel 8.40.0以降を使用している方は「@js()」の方が推奨みたいです。
バージョンを確認して推奨される方をお使いください。
app.js内でコンポーネントにデータを渡す
続いては各コンポーネントにデータを渡すためにapp.jsで設定をします。
app.jsを以下のように設定します。
import React from "react";
import { createRoot } from "react-dom/client";
import ExampleComponent from "./components/ExampleComponent";
import AnotherComponent from "./components/AnotherComponent";
// コンポーネントと対応するDOM要素のマッピング
const components = [
{ id: "example", component: ExampleComponent },
{ id: "another", component: AnotherComponent },
// 新しいコンポーネントが必要な場合は追加していく
];
components.forEach(({ id, component }) => {
const container = document.getElementById(id);
if (container) {
const props = container.getAttribute("data-props");
console.log(props);
const parsedProps = props ? JSON.parse(props) : {};
console.log(parsedProps);
const root = createRoot(container);
root.render(React.createElement(component, parsedProps));
}
});
「const props = container.getAttribute(“data-props”);」ここで対象のid要素に「data-props」属性があればそのデータを取得します。
続いてデータ属性でセットされた値は文字列として扱われるため、JavaScriptオブジェクトに変換するする必要があるので「JSON.parse(props)」でパースします。
パースされたJavaScriptオブジェクトをコンポーネントに渡す処理が「root.render(React.createElement(component, parsedProps));」になります。
これで対象のコンポーネントをデータを渡すことができました。
各コンポーネントでpropsを受け取る
続いては渡されたコンポーネント内でデータを受け取り使っていきます。
import React from "react";
function ExampleComponent(props) {
console.log(props);
return (
<div>
<h1>Hello, React!!!</h1>
{props.message ? <p>{props.message}</p> : null}
{props.user.name ? <p>{props.user.name}</p> : null}
{props.user.email ? <p>{props.user.email}</p> : null}
</div>
);
}
export default ExampleComponent;
ExampleComponentの引数でpropsとして渡されたデータを受け取ります。
あとはそれを表示させるために「props.message」などのようにして各変数にアクセスします。
存在チェックなどが必要ですが、ここでは省いています。
コンソールにpropsを出力していますが、きちんと渡した値が取得できていることが確認できます。
これでLaravelから渡した値をReactで利用することができるようになりました!
一部Reactで実装したい場合に便利
いかがだったでしょうか。
これでLaravelからのデータをReactでも利用することができると思います。
app.js内で各コンポーネントのレンダリングをまとめているので複数のコンポーネントを利用したい場合にも汎用が効くかと思います。
方法は他にもあるかと思いますが、参考になれば幸いです。
これのVueバージョンは以下記事で解説しています。
やり方は同じですが、書き方がVueと異なるので気になる方は参考にしてみてください。