Comment marier Symfony et ReactJS ?

PHP Tour Nantes - Claire Coloma et Suzanne Favot - 18 mai 2017

Comment marier Symfony et ReactJS ?

PHP Tour Nantes - Claire Coloma et Suzanne Favot - 18 mai 2017

Coucou, je suis Claire Coloma

Coucou, je suis Suzanne Favot

ReactJS

Le DOM virtuel

Composants

class TodoList extends Component {
  render() {
    return (
      <div className="well">
        /* Code du rendu */
      </div>
    );
  }
}

Props

<Todo done={false} item={item} />

State

class Todo extends Component {
  constructor() {
	super();

  	this.state = {
      visible: true,
  	};
  }

  markAsDone() {
    this.setState({
	  visible: false,
    });
  }

  render() {
    if (!this.state.visible) {
	  return null;
	}

	return (
	  <li>
	    <span>{this.props.item}</span>
		<button onClick={this.markAsDone.bind(this)}>
			Fait
		</button>
	  </li>
	);
  }
}

L'écosystème React

Twig

{% extends "base.html" %}

{% block content %}

    <h1>Bienvenue</h1>

    {% include 'AppBundle:Homepage:content.html.twig' %}

{% endblock %}

Du React dans Symfony ???

Ça fait peur

On essaye quand même ?

Quelles options ?

Projet 1

Une API Symfony, un front React

Projet 2

Faire du React dans Twig

Javascript compilé et inclus dans Twig

Composants React déclarés à part proprement et compilés en un fichier

{# layout.html.twig #}

{% block body %}
<div
	id="search-page"
	data-categories="{{ categories|json_encode }}"
></div>
{% endblock %}

{% block javascripts %}
	<script type="text/javascript" src="{{ asset('searchpage.js') }}"></script>
{% endblock %}
 // index.js

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

import SearchPage from './SearchPage.jsx';

const searchPageElement = document.querySelector('#search-page');
const getData = (name, json = true) => {
    const value = searchPageElement.getAttribute(`data-${name}`);
    return json ? JSON.parse(value) : value;
};

const element = React.createElement(SearchPage, {
    categories: getData('categories'),
});

ReactDOM.render(element, document.getElementById('search-page'));

Et le référencement ?

On veut mettre du React sur la homepage => problème : pas de référencement => solution : ?

Vu par un robot

Avec Javascript

Sans Javascript

Nuancer à mort : la plupart des robots lisent le js et l'immense majorité des gens aussi
Transition vers React rendu serveur

Rendu serveur

Rendu serveur : fonctionnement

Rendu serveur : pourquoi ?

Avec un serveur node externe

Avec node.js en ligne de commande


exec('node ./test.js', $output);
		

Avec V8Js

$v8 = new V8Js();
$v8->answer = 41;

$js = "var life = {}; life.answer = PHP.answer; life.answer++; life.answer;";

// Affiche 42
$v8->executeString($js);

PhpExecJs


$phpexecjs = new PhpExecJs();

$js = "Math.min(1, 2)";

// Affiche 1
$phpexecjs->evalJs($js);
		

LimeniusReactBundle

LimeniusReactBundle - Mise en place (1)

On crée les composants React à part

LimeniusReactBundle - Mise en place (2)

On register les composants à rendre dans Twig grâce à React on Rails


// registration.js
import ReactOnRails from 'react-on-rails';
import HomePage from './components/HomePage';

ReactOnRails.register({ HomePage });
		

LimeniusReactBundle - Mise en place (3)

On build le code Javascript (par exemple avec Webpack) dans deux fichiers server-bundle.js et client-bundle.js.

LimeniusReactBundle - Mise en place (4)

Enfin, on appelle nos composants en leur passant les props souhaitées.


{{ react_component('HomePage', {'props': {'items': items}, 'rendering': 'both'}) }}
		

Convaincus ?

Ne faites pas du React si vous n'avez pas le besoin factuel et concret d'employer React

X.

Pourquoi utiliser ReactJS avec Symfony ?

Merci ! Et bon appétit ! 🍔

@_ClaireColoma - @SFavot |

Fork me on Github