How To Use React.js In Aurelia

Last updated: February 19, 2016

I am rather smitten with Aurelia but I also just so happen to be a big React.js fan. Due to the fact that Aurelia itself does not ship with its own efficient virtual DOM diffing algorithm for rendering composed views and templates, we can use React.js for the heavier UI stuff.

In Angular we would have done this using a custom directive. In Aurelia we are going to be doing the same, but instead we will be creating a custom element which achieves the same thing as an Angular directive, albeit in a more clean ES6 and Aurelia-like way.

Installing React

Before we proceed we need to make sure that React is installed. We can do this by installing it via JSPM: jspm install react — we also need to install the React DOM package as well for rendering our custom components: jspm install react-dom

We also need to install one more dependency, a JSX loader for System.js. This allows us to use an import declaration to import JSX components. To install this just type: jspm install jsx to add in the loader.

This means we can write React components using JSX syntax and get syntax highlighting, etc.

In the below code example we are going to create a custom element, which will pass data through to React and also has the added advantage of re-rendering itself when the data changes.

Create a custom element

For the sake of sticking with the demo, I recommend saving this file as: “react-element.js” or honestly whatever you want to call it. The filename is irrelevant, I recommend sticking with this name for the sake of the article.

import React from 'react';
import ReactDOM from 'react-dom';
import {customElement, inject, bindable, noView} from 'aurelia-framework';

import MyReactElement from './components/my-react-element.jsx!jsx';

@noView()
@inject(Element)
@bindable('data')
@customElement('react-element')
export class ReactElement {
    
    reactComponent = {};
    
    constructor(element) {
        this.element = element;
    }
    
    render() {
        this.reactComponent = ReactDOM.render(
            <MyReactElement data={this.data} />,
            this.element
        );
    }
    
    bind() {
        this.render();
    }
    
    /**
     * Data Changed
     * 
     * An automatic callback function when our "data"
     * bindable value changes. We need to rebind the React
     * element to get the new data from the ViewModel.
     * 
     * @param {any} newVal The updated data
     * @returns {void}
     * 
     */
    dataChanged(newVal) {
        this.bind();
    }
    
}

Creating a React component

For the above example, let’s create our React component. It will not do much, but it will work nonetheless.

Save the following file as my-react-element.jsx as per the above example and instructions.

import React from 'react';

'use strict';

export default class MyReactElement extends React.Component {
    constructor(props) {
        super(props);
    }
    
    render() {
        if (!this.props.data.length) {
            return null;
        }
        
        return (
            <div>
                <hr />
                <p>Hello, I am a React component being rendered inside of Aurelia.</p>
                <p>This file is located in: src/components/react-components/my-react-element.jsx and is being included from within src/components/custom-elements/react-element.js</p>
                <p>Let's loop through any provided data:</p>
                
                <ul>
                {
                    this.props.data.map(item => {
                        return <li key={item.key}><strong>{item.name}</strong></li>
                    })
                }
                </ul>
            </div>
        );
    }
}

MyReactElement.defaultProps = { data: [] };

Putting it together

The ViewModel

All the ViewModel does is supply our view using the React custom element with data.

Save this file as whatever name you like. For the purposes of this example, I recommend choosing react-example.js – so everything stays inline with the rest of this post.

export class ReactExample {
	
    someData = [];
    
    constructor() {
        this.someData = [
            {key: 'testkey', name: 'Dwayne'},
            {key: 'testkey2', name: 'Rod'},
            {key: 'testkey3', name: 'Todd'}
        ];
    }

}

The View

Okay, now that we have our ViewModel, we need our matching view. The name of the View HTML file needs to match the name of the above ViewModel Javascript file, not the class name. So if you saved the above as “react-example.js” – we will save this View as “react-example.html”

<template>
    <require from="components/react-element"></require>
    
    <h1>This is the homepage</h1>
    <h2>Let's render a React component</h2>
    
    <!-- Our custom element and data passed through to the bindable -->
    <react-element data.bind="someData"></react-element>
  
</template>

Source Code & Demo

You can download and view the source code here on Github. You can also view a demo of the code working here.

Liked it? Take a second to support Dwayne on Patreon!
 

Dwayne

 

13 thoughts on “How To Use React.js In Aurelia

  1. Just found out about how cool react is (particularly for replacing ugly jquery stuff). I’d also like to know how how well Riot 2 works with Aurelia. It’s great how it’s not too hard to use web components in Aurelia.

  2. Hi, cool write up 🙂

    Just thought maybe it’s worth mentioning that with the second example which uses decorators and JSX, you need to install the jsx plugin (http://github.com/floatdrop/plugin-jsx) and add /** @jsx React.DOM */ to the first line of your reactel.js

    Thanks again for writing such a cool and informative post Dwayne, helped me out a lot!

  3. @Zen,

    Because Babel is now including JSX support, and Aurelia recommends and starts you off on Babel, there shouldn’t be any need for additional plugins or pragmas. I’m not 100% sure if that’s true today but it’s definitely around the corner. The plugin you linked to has already deprecated in favor of Babel.

  4. Awesome article Dwayne it really shows the benefits of Aurelias open architecture and how easily different view engines can be plugged in. Also great work cleison with creating the Github repo.

    One great Addon for the article might be to show how Aurelia’s two-way-binding may be used together with React. I’ve created a PR for the above mentioned GitHub Repo depicting this feature.

  5. I am new to aurelia and react and trying to integrate the two but am having difficulty. Is there a low level guide to understand what’s happening here? Or a working example that I actually see it in action?

  6. I have created a Github repository which I am about to add in some examples for using React in Aurelia. I apologise for any confusion, I realise this blog post does not delve into details too much and for some, it might be confusing.

    Sit tight everyone and thank you for your patience.

  7. Hi C. Daniel,

    In the exported component file just define multiple components and then make sure you export them. You can then import one or more components wherever you include the JSX file.

  8. I am a bit confused.. Why would you use react inside Aurelia?

    The only explaination I got was:
    “Due to the fact that Aurelia itself does not ship with its own efficient virtual DOM diffing algorithm for rendering composed views and templates, we can use React.js for the heavier UI stuff.”

    Could you give some examples? What is this heavier UI stuff that Aurelia cannot handle on its own?

Leave a Reply

Your email address will not be published. Required fields are marked *