Skip to content

REACT INTEGRATION

Danny Mcwaves edited this page Apr 7, 2018 · 1 revision

This post assumes that user is already comfortable working with react and is capable of creating and using react components.

Wrapping a react component for Aurelia display.

To use a custom react component in an Aurelia template, it needs to be defined to render a react element when the component is bound to the DOM.

react-component.js

import React, {Component} from 'react';

export default class MyReactElement extends Component {
   
  render() {
    if (!this.props.data.length) {
      return null;
    }
        
    return (
      <div>
        <hr />
        <p>Hello, I am a React component being rendered inside of Aurelia.</p>
        <ul>
          {
            this.props.data.map(item => {
              return <li key={item.key}><strong>{item.name}</strong></li>
            })
          }
        </ul>
      </div>
    );
  }
}

MyReactElement.defaultProps = { data: [] }; // default react prop for the component.

react-element.js

import React from 'react';
import ReactDOM from 'react-dom';
import {customElement, inject, bindable, noView} from 'aurelia-framework';
import Element from 'react-component'; // this is the react component you created.

@noView()
@inject(Element) // inject element to which we render component
@bindable('data') // bind data from Aurelia class to react prop
@customElement('react-element') // define the name of the custom element.
export class ReactElement {

  constructor(element) {
    this.element = element;
  }

  render() {
    // render the react component in the inject element with bound data as a prop.
    ReactDOM.render(<Element 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();
  }
}

Create and export a custom class the defines the custom element (CustomElement).

Bind any property to the react component if available with bindable.

Render the component with ReactDOM when the class is bound to the DOM.

In case the data changes with time, define an arbitrary callback that re-renders the component with the data property changes.

The View Template

Require the custom component from the file (react-element.js) and use the custom component in the Aurelia template.

<template>
    <require from="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>
Clone this wiki locally