Getting started with ReactJS & Drupal (Fully-Decoupled)

Let’s react with Drupal :)

The only thing which is constant is change. Remember how the websites looked 10 yrs ago. Just in case you want to go to flashback here is a reference link: https://www.hongkiat.com/blog/websites-we-visit-how-they-look-like-10-years-ago/. With digital experience enhancing day by day and rapid advancement in technologies around, every day we see an improved version of the web world. And so to keep the ball rolling, as techguards we need to sharpen our skills timely.

I remember when I used Marquee HTML tag in my school days and here we are, discussing whole together different world today. API-first, or “decoupled”, architecture is quickly becoming the most popular way to create world-class digital experiences. This empowers developers with a great amount of flexibility and end-users with awesome user experience and that’s what we want.

Decoupled Architecture

To understand the term “Decoupled” we need to understand what “Coupled” is. A coupled (also known as “traditional” or “monolithic”) CMS knits together the front- and back-ends. Working off the same application, developers and content managers make adjustments to the back-end while users interact with the front-end, but both are experiencing, viewing, and interacting with the same system.

While in a decoupled CMS, the front-end and back-end are separated. The CMS handles the back-end, and a delivery system handles the front with an application programming interface (API) that connects them for publishing.

Source: https://clutch.co/web-developers/resources/coupled-decoupled-headless-CMS

Introduction to React & Drupal

React JS

React is a JavaScript library for building user interfaces. Started in 2013, React has quickly grown in popularity due to its declarative style and lack of assumptions about your technology stack. In the last few years, a large ecosystem has grown around React. This includes high-quality libraries, conferences, and increased demand for developers with React skills.

Drupal

Drupal is an open-source content management system with a robust suite of tools for modeling data, implementing editorial workflows, and coding custom application logic. There is also excellent support for JSON API or GraphQL web services, making it a good choice as the backend for your React application.

In this tutorial, we will be developing a fully decoupled simple listing website to understand some baseline information and get started integrating React and Drupal together. We will be building Travel Destinations Listing Website.

Let’s have a glance at how we will proceed to build this fully decoupled application:

  • Configure Drupal to serve data
  • Create React App
  • Define React Components
  • Fetch Data and Display

Step 1: Configure Drupal to serve data

Initially, we need to set up our backend i.e Drupal, build the content architecture and then expose this data as web service API.

1. Setup Drupal using Composer

Setting up Drupal has never been so easy especially with the Composer. For those who are not familiar with the Composer, it’s a PHP dependency manager which can be used to download Drupal, Drupal contributed projects (modules, themes, etc.), and all of their respective dependencies. Firstly we need to have Composer on our system if you already don’t have, follow this https://getcomposer.org/download/ to download and install Composer. Now we need to create a Drupal project using the following command:

This command will take several minutes to execute and ‘travel_destinations’ being the directory where Drupal project will be installed.

This command downloads latest Drupal (version 8.x) in the web directory and other dependencies in the vendor directory. Now we need to create a virtual host (say http://td-drupal.local) pointing to web directory so that we can access it on the web browser.

2. Install Drupal

Before installing Drupal we need to create a database which Drupal will be using and corresponding user with all privileges on that database. There are multiple ways to install Drupal, either via interactive UI provided by default by Drupal (which can be accessed via visiting http://td-drupal.local in the browser) or using drush:

https://www.drupal.org/docs/8/install
Or
https://drushcommands.com/drush-9x/site/site:install/

Or you can even use Drupal Console.

3. Download and Install Required Modules

Drupal modules are like plugins to extend Drupal core functionalities. Now we need to add JSON API module and for this, we can download the module using composer and then enable it. Additionally, let’s download the Admin Toolbar module as well for faster navigation.

Execute the following command in the travel_destinations folder (the root of project repo):

This will download and place the JSON API module in travel_destonations/web/modules/contrib directory. Enable the module either via logging into the website using the credentials used while installation in the previous step and navigating to http://td-drupal.local/admin/module page or use drush packaged in your project.

4. Create Content Type & some sample content

A Drupal “content type” is a particular kind of content. By default Drupal ships with ‘Article’ and ‘Basic Page’ content type. Drupal makes it easy for you to make your own content types. In our case, we are going to create a Destination content type.

Login to website using credentials used at the time of installation and navigate to Structure > Content Type.

Then add new content type and give the name as ‘Destination’. That’s it no further structural decisions as of now.

Let’s add some sample destinations with the title and some description, visit http://td-drupal.local/node/add/destination to add some sample destinations.

5. Review JSON web service API

Next step is to set up API data in Drupal for React. We already have enabled the JSON API module in the third step earlier. The beauty of this module is :

JSON API module requires no configurations, as soon enabled it just works.

This module exposes Drupal entities as a web service API.

To try out visit http://td-drupal.local/jsonapi

And hence destination contents are available as JSON data on http://td-drupal.local/jsonapi/node/destination

Observe the content under data. Title and body values are shipped under attributes key.

JSON API module is not only limited to the above functionality, but this also comes with a lot more, check here: https://www.drupal.org/docs/8/modules/jsonapi

Perfect so the backend is ready!

Step 2: Create React App

Once we are ready with JSON API exposing the required data, we now need to set up our Front-end to use this data and display in the application. There are numerous ways to set up a new ReactJS project and configure as per our requirements. In this example, we are going to use create-react-app provided by Facebook. This allows us to create React apps with no build configuration.
Open terminal and change directory to travel_destinations (the root of the project). Here, in a new directory say ‘react_app’ we will be installing create-react-app. Ensure you have NodeJS version 6 or higher installed.

Execute following commands to install and launch create-react-app

This will open http://localhost:3000 on your browser with the following screen.

Create React App generates scaffold files which basically is generating this page. If we closely look into the files created by the app under react_app directory, we find two folders public and src. Folder ‘public’ contains public assets and index.html file and src directory contains index.js which renders React Application into your website.

Now, before proceeding further let’s understand

  • React Components and Props
  • State
  • JSX

React Components

Most web development in the past years is based on the traditional top-down design provided by page and screen. These designs are processed by breaking them down in containers, grids and elements. Even Drupal core works in a similar fashion. In recent days we have seen a shift in the approach, where we focus on the individual atomic elements which combine to build User Interface. This is relatable to an object-oriented architecture where an object is compared to a real-world entity and has some properties and behaviors. Similar is the React Component. Developers write reusable components, starting at the “atomic” level, and work their way up to collections of atoms, layouts, and screens. As per React Official documentation:

Components let you split the UI into independent, reusable pieces, and think about each piece in isolation.

Props

A component is like a container which at the end is there to return some output based on some input like if we consider button as a component then to show HTML button we give some label as well. Now, if we are creating reusable components then our approach should return output based on our requirements which we pass like inputs and these inputs are props.

Learn more about components and props.

State

The state can be defined as an attribute of Component which defines a particular condition of the component and helps in tracking and manipulation of the behavior of the Component. For example, the status of an Accordion can be closed or open. So Accordion is the component over here and status can be considered as a state. Heading and Description can be considered as props for a reusable Accordion component.

JSX (Javascript XML)

Consider this variable declaration:
const element = <h1>Hello, world!</h1>;
This funny tag syntax is neither a string nor HTML.

It is called JSX, and it is a syntax extension to JavaScript. We recommend using it with React to describe what the UI should look like. JSX may remind you of a template language, but it comes with the full power of JavaScript.
Source: ReactJS Documentation

Step 3: Define React Components

Defining Components is a very important step in planning for your React Application. A React Application is basically a nested React Component which contains another React component as discussed above. And this top-level Component is rendered in the HTML.

So, as we are building Travel Destinations Listing Application, we basically are showing Destination Item which can be thought of the atomic level element or component as per React vocabulary. Multiple Destination Items combined together generates Destination List and this Destination List is the main part of our App.

So, we have an overview of the React Components in our application:

— App
 — — DestinationList
 — — — DestinationItem

Important is to analyze that App itself is a React component. Let’s start building our application. Under react_app > src directory create Components directory. Let’s further classify Destination related components in the Destination directory. So under react_app > src > Components > Destination we define DestinationItem component. Create a file DestinationItem.js and define a component as:

In the first line, we are importing React Component which we are using to extend our DestinationItem component from. Statement ‘export default’ is to export the component class. We are defining mandatory render() function which is returning JSX (however it’s a plain HTML for now in the above case). For now, we are defining prototype components, actual data will be fetched and displayed on the next steps.

Now let’s create next component DestinationList which will display this DestinationItem. Here we will see nesting. Create DestinationList.js file besides the previous DestinationItem.js

The code above itself quite clearly speaks what we are doing. For now, let’s just display only one item on the list. Once we start getting output from our components in the browser window, it will be easy for us to move forward.

Next step in this process should come in our mind by default. Yes, we will now edit App.js to include DestinationList component.

As soon as we save this file we will see the results as per our expectation in the browser now as our app is already up and running.

Refer following repo for sample code: https://github.com/purushotamrai/travel_destinations/tree/step-3-define-components/react_app

Step 4: Fetch Data & Display

Next step is to make use of our Drupal JSON API response, fetch that and display that using our components. We will make use of fetch API provided by native javascript and will play with state and props to finally display data. We are now going to learn more about state and props and their actual usage which will bring us closer to ReactJS.

  1. Fetch Data

So, the idea behind is at the time of initialization of ‘App’ react component we will fetch URL and set that in the state of App and whenever state is updated the component automatically is re-rendered. We cannot modify the state directly. Instead, we update the state using the setState method. And to trigger all this we will use one lifecycle method ‘componentWillMount’ and this method is only called one time, which is before the initial render. Add a constructor in App.js as follows:

Here we are defining state and setting data (under state) as null. We define two other functions loadDestinations and updateData and bind ‘this’ (App component) to these methods. Method loadDestinations will be used to fetch data from Drupal API.

Define a constant LIST_URL next to import statements as

And inside class App let’s add loadDestinations method as:

We first send the request with URL and options and then Get a response from the server and convert it to JSON. Then we are calling the updateData function with this data. If the request fails we catch any error in the last line.

Read more about Fetch API: https://scotch.io/tutorials/how-to-use-the-javascript-fetch-api-to-get-data

Add updateData function as well which basically sets state data to the received JSON data.

This will re-render the component. Let’s add a lifecycle method which will trigger this whole process.

This data now needs to be passed to the DestinationList class as a prop. So, update render() function as well.

This is how we communicate with the nested classes using props.

Source Code: https://github.com/purushotamrai/travel_destinations/tree/step-4.1-fetch-data

2. Display Data

As in the previous step we send data to DestinationList, we now collect that data in DestinationList class in DestinationList.js file and after quick check create an array of DestinationItem passing the item.

Update the render function of DestinationList as:

We are using Array.map function to send the complete item using {…item} to DestinationItem class as props and key as item.id and finally, we will be using item passed over here in DestinationItem class to replace the placeholders created earlier. Update render function of DestinationItem component as:

When we passed {…item} from DestinationList class to this DestinationItem class all the array data one by one is passed as props to this class and hence we access title and body using this.props as this.props.attributes.title & this.props.attributes.body.value.

Refresh the page in the browser and you will see an error. So we were expecting our data and we ended up producing an error in console. We expect error related to “No ‘Access-Control-Allow-Origin’ header is present on the requested resource drupal…” which basically does not allow Drupal site’s JSON API data to be used by React Application because of different domains. So, we need to resolve this at Drupal end. Drupal easily allows us to do the required changes. We just need to update services.yml file present under Drupal which is web/sites/default directory. If the file services.yml is not already present there, we just need to copy default.services.yml as services.yml in the same directory and do some changes to allow CORS (Cross-Site HTTP requests).

See https://www.drupal.org/node/2715637 for more details around this. The support provided by Drupal is really awesome as always.

And here we go, refresh the page and we should see a list of Travel Destinations, so what are you waiting for, decide from the list and pack your bags. This is what we were waiting for. Happy Journey!

Source Code: https://github.com/purushotamrai/travel_destinations/tree/step-4.2-display-data

What’s Next?

So, this just marks the starting point to explore Drupal and React further and create awesome applications. We can find useful resources around the web to further deep dive into the numerous possibilities. For example, as the next step for Drupal Developers, we can explore https://medium.freecodecamp.org/learning-react-roadmap-from-scratch-to-advanced-bff7735531b6

And for React JS Developers https://reactfordrupal.com/tutorials/drupal-for-react-developers/

So plan and carry on, Learning is a journey that never ends.