· 5 min read
Du React avec Symfony
Découvrez comment intégrer React dans votre application Symfony HYPER simplement
Objectifs
Dans cet article, nous allons voir comment intégrer React dans une application Symfony. Nous allons voir comment créer un composant React, le rendre disponible dans notre application Symfony et l’utiliser dans une page Twig avec l’aide de Webpack Encore et Symfony UX React !
Installons un projet Symfony
- Commençons par créer un projet Symfony 6
symfony new ReactSymfony --webapp
- Puis installons les dépendances nécessaires
composer require symfony/webpack-encore-bundle
composer require symfony/ux-react
- Téléchargeons ensuite les dépendances NPM
npm install --force
- Installons Tailwind CSS
npm install -D tailwindcss postcss autoprefixer postcss-loader
npx tailwindcss init -p
- Ajoutons PostCSS dans le fichier
webpack.config.js
Encore
// ...
.enablePostCssLoader()
;
- Modifions la configuration de Tailwind CSS dans le fichier
tailwind.config.js
/** @type {import('tailwindcss').Config} */
module.exports = {
content: [
"./assets/**/*.js",
"./templates/**/*.html.twig",
],
theme: {
extend: {},
},
plugins: [],
}
- Ajoutons les styles de Tailwind CSS dans le fichier
assets/app.css
@tailwind base;
@tailwind components;
@tailwind utilities;
Créons un contrôleur ReactController
- Créons un contrôleur
ReactController
avec la commande suivante
symfony console make:controller ReactController
- Modifion notre fichier Twig
react/index.html.twig
{% extends 'base.html.twig' %}
{% block title %}Hello ReactController!
{% endblock %}
{% block body %}
<div class="bg-white">
<div class="mx-auto max-w-7xl py-16 px-4 sm:py-24 sm:px-6 lg:px-8">
<div class="text-center">
<p class="mt-1 text-4xl font-bold tracking-tight text-gray-900 sm:text-5xl lg:text-6xl">Ceci est une démo de React dans une application Symfony</p>
<p class="mx-auto mt-5 max-w-xl text-xl text-gray-500">Ceci est une démo de React dans une application Symfony</p>
</div>
</div>
</div>
{% endblock %}
Créons et utilisons un composant React
- Un peu de configuration avant de commencer, installez les dépendances suivantes
npm install @babel/preset-react@^7.0.0 --save-dev
- Et activons React dans le fichier
webpack.config.js
Encore
// ...
.enableReactPreset()
;
```json
{
"presets": [
"@babel/preset-env",
"@babel/preset-react"
]
}
- Ajoutons la gestion des composants React dans le fichier
assets/app.js
import { registerReactControllerComponents } from '@symfony/ux-react';
registerReactControllerComponents(require.context('./react/controllers', true, /\.(j|t)sx?$/));
- Créons un composant React (issue de la documentation officielle de Symfony) dans le fichier
assets/react/controllers/MyComponent.jsx
import React from 'react';
export default function (props) {
return <div>Hello {props.fullName}</div>;
}
- Utilisons notre composant React dans notre code Twig:
{% block body %}
<div class="bg-white">
<div class="mx-auto max-w-7xl py-16 px-4 sm:py-24 sm:px-6 lg:px-8">
<div class="text-center">
<p class="mt-1 text-4xl font-bold tracking-tight text-gray-900 sm:text-5xl lg:text-6xl">Ceci est une démo de React dans une application Symfony</p>
<p class="mx-auto mt-5 max-w-xl text-xl text-gray-500">Ceci est une démo de React dans une application Symfony</p>
<div {{ react_component('MyComponent', { 'fullName': 'YoanDev' }) }}></div>
</div>
</div>
</div>
{% endblock %}
- Et voilà, notre composant React est maintenant disponible dans notre application Symfony !
Un composant React plus complexe
Pour la suite nous allon sutiliser la superbe librairie Headless UI qui permet de créer des composants React très facilement, bien adpatés à Tailwind CSS 💗
* Installons Headless UI
```bash
npm install @headlessui/react
- Indiquons à Tailwind CSS de surveiller nos composants React
/** @type {import('tailwindcss').Config} */
module.exports = {
content: [
"./assets/**/*.js",
"./templates/**/*.html.twig",
"./assets/react/controllers/*.jsx",
],
theme: {
extend: {},
},
plugins: [],
}
- Créons un composant React plus complexe dans le fichier
assets/react/controllers/Modal.jsx
import React from 'react';
import { Dialog, Transition } from "@headlessui/react";
import { Fragment, useState } from "react";
export default function MyModal() {
let [isOpen, setIsOpen] = useState(true);
function closeModal() {
setIsOpen(false);
}
function openModal() {
setIsOpen(true);
}
return (
<>
<div className="fixed inset-0 flex items-center justify-center">
<button
type="button"
onClick={openModal}
className="rounded-md bg-black bg-opacity-20 px-4 py-2 text-sm font-medium text-white hover:bg-opacity-30 focus:outline-none focus-visible:ring-2 focus-visible:ring-white focus-visible:ring-opacity-75"
>
Open dialog
</button>
</div>
<Transition appear show={isOpen} as={Fragment}>
<Dialog as="div" className="relative z-10" onClose={closeModal}>
<Transition.Child
as={Fragment}
enter="ease-out duration-300"
enterFrom="opacity-0"
enterTo="opacity-100"
leave="ease-in duration-200"
leaveFrom="opacity-100"
leaveTo="opacity-0"
>
<div className="fixed inset-0 bg-black bg-opacity-25" />
</Transition.Child>
<div className="fixed inset-0 overflow-y-auto">
<div className="flex min-h-full items-center justify-center p-4 text-center">
<Transition.Child
as={Fragment}
enter="ease-out duration-300"
enterFrom="opacity-0 scale-95"
enterTo="opacity-100 scale-100"
leave="ease-in duration-200"
leaveFrom="opacity-100 scale-100"
leaveTo="opacity-0 scale-95"
>
<Dialog.Panel className="w-full max-w-md transform overflow-hidden rounded-2xl bg-white p-6 text-left align-middle shadow-xl transition-all">
<Dialog.Title
as="h3"
className="text-lg font-medium leading-6 text-gray-900"
>
Payment successful
</Dialog.Title>
<div className="mt-2">
<p className="text-sm text-gray-500">
Your payment has been successfully
submitted. We’ve sent you an email
with all of the details of your
order.
</p>
</div>
<div className="mt-4">
<button
type="button"
className="inline-flex justify-center rounded-md border border-transparent bg-blue-100 px-4 py-2 text-sm font-medium text-blue-900 hover:bg-blue-200 focus:outline-none focus-visible:ring-2 focus-visible:ring-blue-500 focus-visible:ring-offset-2"
onClick={closeModal}
>
Got it, thanks!
</button>
</div>
</Dialog.Panel>
</Transition.Child>
</div>
</div>
</Dialog>
</Transition>
</>
);
}
- Et utilisons le dans notre code Twig:
{% block body %}
<div class="bg-white">
<div class="mx-auto max-w-7xl py-16 px-4 sm:py-24 sm:px-6 lg:px-8">
<div class="text-center">
<p class="mt-1 text-4xl font-bold tracking-tight text-gray-900 sm:text-5xl lg:text-6xl">Ceci est une démo de React dans une application Symfony</p>
<p class="mx-auto mt-5 max-w-xl text-xl text-gray-500">Ceci est une démo de React dans une application Symfony</p>
<div {{ react_component('MyComponent', { 'fullName': 'YoanDev' }) }}></div>
<div {{ react_component('Modal') }}></div>
</div>
</div>
</div>
{% endblock %}
- Modifions notre fichier
assets/react/controllers/Modal.jsx
pour pouvoir passer des paramètres à notre composant React
export default function MyModal(props) {
// ...
}
- Et utilisons une props pour changer le libelé de nos boutons
// ...
<div className="fixed inset-0 flex items-center justify-center">
<button
type="button"
onClick={openModal}
className="rounded-md bg-black bg-opacity-20 px-4 py-2 text-sm font-medium text-white hover:bg-opacity-30 focus:outline-none focus-visible:ring-2 focus-visible:ring-white focus-visible:ring-opacity-75"
>
{props.button}
</button>
</div>
// ...
<div className="mt-4">
<button
type="button"
className="inline-flex justify-center rounded-md border border-transparent bg-blue-100 px-4 py-2 text-sm font-medium text-blue-900 hover:bg-blue-200 focus:outline-none focus-visible:ring-2 focus-visible:ring-blue-500 focus-visible:ring-offset-2"
onClick={closeModal}
>
{props.button}
</button>
</div>
// ...
- Et enfin, depuis notre fichier Twig on peut passer des paramètres à notre composant React
<div {{ react_component('Modal', { 'button': 'YoanDev Button'}) }}></div>
Conclusion
Nous avons vu comment utiliser React dans une application Symfony. Nous avons vu comment créer un composant React, comment l’importer dans notre application Symfony et comment l’utiliser dans un fichier Twig. Nous avons aussi vu comment passer des paramètres à notre composant React depuis notre fichier Twig.
Nous en avons profité pour voir comment utiliser TailwindCSS et HeadlessUI pour notre plus grand plaisir.