Many of the resources around React are geared towards starting a new single-page app. The official documentation shows you how to add React to a website, but doesn’t go into much detail about adding it to a larger scale project.
This article will walk you through the method I used to piecemeal React into an existing multi-page app, whilst continuing to use existing back-end routing and template data. This will be particularly helpful if you don’t have API endpoints built out yet.
I’ve been working on an large application with a behemoth code base that has been developed over the last 10–15 years. The majority of the code base was using a custom MVC written in PHP, with Twig for templating. jQuery was used where dynamic interactions were required, in a fairly messy and inconsistent format.
APIs didn’t really exist yet, but there was a push to start moving towards the new standard for web development. I was in charge of the front-end side of things — which meant designing and implementing a new architecture which could be gradually rolled out through the code base.
Setting up React
To start integrating React into our app — we’re going to install React and Webpack. I will leave out installing and setting up Babel for brevity.
npm install react react-dom --savenpm install webpack webpack-cli --save-dev
We’ll start our React development by creating a basic presentational component:
Then we’ll create a container component. This will be responsible for importing and displaying presentational components, as well as holding any state:
Webpack needs an entry point which imports container components, then attaches them to your DOM elements. We will attach the ExamplePage component to an HTML element with an ID of
example-react-container, which we will set up shortly.
We can now add our Webpack config:
After doing this (and setting up Babel) you should be able to run
webpack in your CLI, which will compile your React bundle to a
Last thing we need to do is create that HTML element that I mentioned earlier —
Hopefully when you navigate to your example page now — you should see the example component working.
We have now integrated React onto one page. This is all fairly straight-forward — things start to get a bit more complicated when you start to create more screens and need to access server-side data in React.
Accessing server-side data in React
From what I can tell — it is assumed that you will be able to get all of your required server-side data in React via XMLHttpRequests. There doesn’t appear to be a standard way to get data from your template into React.
With the application I was working on — moving all server-side data from template payloads and Twig helpers to APIs wasn’t going to happen overnight. After a bit of Googling I stumbled upon this StackOverflow post, and a library mentioned in the final comment called ReactHabitat. This library allows you to pass through data from your template into React like this:
<div data-component="MyReactComponent" data-prop-title="My Title" ></div>
Let’s start setting this up by installing the package:
npm install react-habitat --save
We’ll adjust our app.js entry file to use ReactHabitat to attach our containers to DOM elements:
Then we’ll adjust our template to suit the new way that React gets attached:
We can now pass server-side template data through to our container component:
We pick it up from React with the props system:
Conclusion and next steps
We can now create pages in React, which utilise reusable presentational components across your app. We can also access server side data inside React that was available inside your template 🎉
Note: I chose to move whole pages into React rather than sprinkling React components through templates (which is also possible with ReactHabitat). The reason for this is for simplicity, especially when components on the same page need to communicate with each other (state is stored in container components and can be passed down into child components).
Code splitting is something you will want to look into as your application grows, as the user will currently have to download data for every React page when they visit just one page. ReactHabitat has support for this according to their documentation. I have yet to explore this, perhaps a topic for another article 😁
If you are progressively moving from traditional templating & jQuery to React — I’d love to hear how you’re doing it and how it’s going! I find it strange that this isn’t a common problem talked about more often.