Reusable React components are not so popular in Laravel. By reusable, I mean component that can be embedded in Blade with all benefits offered by Laravel Mix - the way it works with Vue. This is because of the architecture and how loaders work with those tools. On the other side React is a library (most often used to create SPA) and there are many possible implementations. In my humble opinion this is why the Laravel ecosystem is Vue-centric.
There is no point in comparing React and Vue, each has its own advantages - I use both. In this post we will focus only on React, Blade templates and how to connect them together to make our development even more enjoyable! Let's try.
The library we are gonna use is react-supervisor.
# this package helps
npm i react-supervisor
# optional, if you haven't installed it yet
npm i react react-dom
If you are not using the latest version of React (^18.0.0), please install the appropriate version of react-supervisor
. Supported versions link.
Open webpack.mix.js
and add .react()
line (please adjust the path of source and output).
// webpack.mix.js
mix
.js('resources/js/app.js', 'public/js')
.react();
After that you have to run npm run dev
it will install Babel presets for React. It may failed if you never used react in your project, but there will be a proper message in the console - this is how Laravel Mix and npm works. If you saw an error try to run it again and it should complete with success.
npm run dev
We are ready to use it, let's create a simple component and register it with react-supervisor
.
// resources/js/app.js
import React from "react";
import { ReactSupervisor } from "react-supervisor";
const SomeReactComponent = (props) => {
return <button>I am a react component</button>
};
ReactSupervisor.registerComponent(".some-selector", SomeReactComponent)
// ReactSupervisor.registerComponent(".other-selector", OtherComponent)
ReactSupervisor.initialize();
Now in Blade templates you can embed your components with selector you used in registerComponent
method. In this example, any DOM element with .some-selector
class will become a parent node for SomeReactComponent
and all data-
attributes will be passed to React component.
// blade template
<div class="some-selector"></div>
<span class="some-selector"></span>
In react-supervisor
there is also a cast feature. Because the HTML attribute values are string it will help you with casting the data. Here is the list of all supported types in version ^4.0.0:
- string
- boolean
- float
- number
- json
To cast a data type you must use a naming convention
Attribute in Blade | Key name in React props | Value |
---|---|---|
data-cast-number-age="3.14" | age | 3 |
data-cast-float-pi-value="3.14" | piValue | 3.14 |
data-cast-json-data='{"piValue": 3.14}' | data | { piValue: 3.14 } |
data-cast-boolean-is-active="true" | isActive | true |
data-cast-boolean-is-active="0" | isActive | false |
data-cast-string-index="0001" | index | "0001" |
And here is an example
<!-- blade template -->
<div class="some-selector" data-cast-number-age="64"></div>
// In React component you can access age property via props
const SomeReactComponent = (props) => {
props.age; // 64
return <button>I am a react component</button>;
};
Summary
If you use Blade templates and want to use React without building SPA then it will certainly help you. Maybe that's not an ideal use of React you could dream of, but it works 🎉.