• Skip to primary navigation
  • Skip to main content
  • Skip to primary sidebar

I Like Kill Nerds

The blog of Australian Front End / Aurelia Javascript Developer & brewing aficionado Dwayne Charrington // Aurelia.io Core Team member.

  • Home
  • Aurelia 2
  • Aurelia 1
  • About
  • Aurelia 2 Consulting/Freelance Work

How To Use React.js In Aurelia

Aurelia 1 Tutorials, Javascript · March 19, 2015

I am rather smitten with Aurelia but it’s hard to deny the popularity of React. To avoid a situation where it’s React or nothing, to get the best of both worlds, we can use React inside of Aurelia.

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 ESNext 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: npm install react --save — we also need to install the React DOM package as well for rendering our custom components: npm install react-dom --save

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';

@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.js as per the above example and instructions.

import React from 'react';

export default class MyReactElement extends React.Component {
    constructor(props) {
        super(props);
    }
    
    render() {
        if (!this.props.data.length) {
            return null;
        }
        
        return (
            <div>
                <hr />
                Hello, I am a React component being rendered inside of Aurelia.
                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
                Let's loop through any provided data:
                
                <ul>
                {
                    this.props.data.map(item => {
                        return <li key={item.key}>{item.name}</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>
    
    
    <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.

Dwayne

Leave a Reply Cancel reply

17 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
Bennett Miller
Bennett Miller
7 years ago

Nice article – PS, your Create the View code example about the template is empty.

0
Roland
Roland
7 years ago

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.

0
Zen Savona
Zen Savona
7 years ago

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!

0
Neverfox
Neverfox
7 years ago

@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.

0
cleison
cleison
7 years ago

Here a working example https://github.com/cscleison/AureliaReactPOC

0
Vildan Softic
Vildan Softic
7 years ago

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.

0
Florian
Florian
7 years ago

Great post, cool to see that this is all possible.

0
Alf
Alf
7 years ago

+1 for how this would work with http://riotjs.com/

0
C. Daniel
C. Daniel
6 years ago

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?

0
Dwayne
Dwayne
Author
6 years ago

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.

0
C. Daniel
C. Daniel
6 years ago

How would I do more than one component using the same jsx?

0
Dwayne
Dwayne
Author
Reply to  C. Daniel
6 years ago

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.

0
Liisi
Liisi
5 years ago

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?

0
Lars
Lars
5 years ago

I’m trying to work through this same setup except using Typescript (and TSX files in place of JSX). So far, I get a “syntax error” on load somewhere inside SystemJS.

0
Lars
Lars
5 years ago

Turns out the problem was the TSX not being compiled and retrieved correctly. The vanilla code from your GitHub repo works fine (on Node v6, though not on v8 thanks to node-sass incompatibility). And from what I can see starting from the Aurelia CLI is going to be very difficult at this point. I’m going to try next starting from the latest ES skeleton and reproducing what you have. If I can get *that* working I might be able to reproduce that in a Typescript-based skeleton. Here’s hoping ๐Ÿ™‚

0
Alfred Lopez
Alfred Lopez
2 years ago

How will this work with components already created in React? Would we have to extend each React component that we use?

Thanks!

0
Superdoei
Superdoei
2 years ago

Just putting this out here in case anyone (still) wants to try this:

This repo, which is heavily based on the article above, helped me getting this to work.
Note that you might need to update some things depending on your needs (It’s all old code) – in my case I had to update the babel plugins & had to separate the loaders, as we are using ts-loader for .js files (so add babel-loader for .jsx files)

https://github.com/allencoded/aurelia-react-skeleton/wiki/Aurelia-with-React-using-Webpack

0

Primary Sidebar

Popular

  • Testing Event Listeners In Jest (Without Using A Library)
  • How To Get The Hash of A File In Node.js
  • Thoughts on the Flipper Zero
  • Waiting for an Element to Exist With JavaScript
  • How To Paginate An Array In Javascript
  • How To Mock uuid In Jest
  • How to Use Neural DSP Archetype Plugins With the Quad Cortex
  • How To Get Last 4 Digits of A Credit Card Number in Javascript
  • How To Decompile And Compile Android APK's On A Mac Using Apktool
  • NBN Box Installed Inside of Garage, Where Do You Put The Modem?

Recent Comments

  • Kevmeister68 on Start-Ups and Companies That Embrace Work From Anywhere Will Be More Likely to Survive the Coming Recession in 2023
  • kevmeister68 on What Would Get People Back Into the Office?
  • Dwayne on PHP Will Not Die
  • Dwayne on How to Create a Blockchain With TypeScript
  • kevmeister68 on PHP Will Not Die

Copyright © 2023 ยท Dwayne Charrington ยท Log in

wpDiscuz