Shifting my frontend from Symfony to React stack episode 1: a first React component.

Florent Destremau
4 min readJan 23, 2017

--

A more permanent link to this article is now available here on my personal site.

When I started to develop my startup’s website Windoo, I wanted to get online as soon as possible, so I went for the safest tool I had: Symfony. Backend, frontend, it is still for me the most convenient all-around framework. When came the time to build an app, I had heard of React Native so I decided to go full hybrid. So we had an Api section in our Symfony controllers, the services where in common, everything was looking good !

And then it hit me. I only used React Native on the app but didn’t think enough about the website ! So I decided that I should migrate the whole website in React as well, and leave out the classic Symfony website.

So I will relate my journey in this transition here.

Update: Why the hell did I need to migrate in the first place

I had some feedback on this article (and I thank the people concerned), and it seemed I didn’t get to explain why exactly I was trying so badly to go towards a React front-end website. So these are the main reasons:

jQuery fatigue. Yes I use jQuery and I love it…for a simple slide up / slide down effect. But for a more complex component I grew tired of spaghetti code with onclick effects, no state / templating, and complex library management

DRY. I have a React Native app, so it would be a bit of a waste for me to maintain a jQuery-based frontend while having a full set of services in React available. So I am planning on having at the end of the process a React website and a React Native app that uses the same common core services & code, and simply different templates for rendering.

Step 1: creating a simple React Component

We’ll start off with simple stuff: a simple component.

import React from 'react';class Checkout extends React.Component {
render() {
return (
<div>
Hello React !
</div>
);
}
}
export default Checkout;

Then we insert it in the DOM:

import React from 'react';
import ReactDOM from 'react-dom';
import Checkout from './components/Checkout';
const checkout = document.getElementById('react-checkout-root');if (checkout) {
try {
ReactDOM.render(<Checkout />, checkout);
} catch (error) {
console.error(error);
}
}

And finally we load our Symfony template:

{# AppBundle::Event:show.html.twig #}{% block body %}<h1>{{ event.title }}</h1><div id="react-checkout-root"></div>{% endblock %}{% block javascripts %}
{{ parent() }}
{% javascripts 'react-build/js/build.min.js' %}
<script src="{{ asset_url }}"></script>
{% endjavascripts %}
{% endblock %}

And voilà ! Now in our Symfony page we have booted a React app.

Step 2: connecting the React component to Symfony

Now we would like our react component to take into account the context of its location (remember, we have a standard PHP — Symfony website for now, so only server side rendered static html pages). So when I want to load the checkout for an event, I need the event id, price, title, etc…and all these are in my twig environment event variable ! So let’s give these to the component we’re booting:

{% block body %}<h1>{{ event.title }}</h1><div
id="react-checkout-root"
data-event-id="{{ event.id }}"
data-event-title="{{ event.title }}"
data-event-price="{{ event.formattedPrice }}"
></div>
{% endblock %}

We’re going to use the dataset property:

import React from 'react';
import ReactDOM from 'react-dom';
import Checkout from './components/Checkout/Checkout';
const checkout = document.getElementById('react-checkout-root');
if (checkout) {
try {
ReactDOM.render(
<Checkout {...(checkout.dataset)}/>,
checkout
);
} catch (error) {
console.error(error);
}
}

So now our properties are passed to the component, let’s use them !

import React from 'react';class Checkout extends React.Component {
constructor(props) {
super(props);
}

render() {
return (
<div>
<p>
You want to book our event
#{this.props.eventId}: {this.props.eventTitle} ?
</p>
<p>Price: {this.props.eventPrice}</p>
<button>Book this !</button>
</div>
);
}
}
export default Checkout;

Easy, right ?

Notice how the the data parameters that I passed in kebab-case and got in return my variables in CamelCase, nice for conventions !

Step 3: profit !

Now that we have our “global” properties set up we have a fully autonomous react component right in the middle of a Symfony website! Add it a state, nested components and even some networking and you’re good to go !

This was you can prepare your migration by building your core components, and thus improving your UX, without (yet) worrying about migrating totally to React (because you know, routing, SEO, and stuff…)!

Bonus step: miscellaneous.

  • I personally preferred to pass only the event-id as a parameter and fetch the rest of the necessary information with ajax request using axios, as simple yet powerful ajax library. Yes, I am aware that I could be making some unnecessary requests, but this way my component is fully autonomous so it’s really a plug-and-play component.
  • The very powerful thing I was glad to profit from for now was that the PHP sessions cookies is still usable so all my authentication made with Symfony is completely usable as it is without worrying about tokens, which is a blessing for a React newcomer like me !

Liked the article ? Please let me know !

I’ll publish my progress towards a full React website.

--

--