Skip to content

Example: REACTJS with No Build Step

Julian Knight edited this page Dec 21, 2022 · 1 revision

This is an example for uibuilder based on Based "React in One Minute". It demonstrates using React with no build tooling. React is loaded as a script tag.

NB: Set up to work with uibuilder v5+. Commented out code gives the older config.

index.html

<!doctype html>
<html lang="en"><head>

    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">

    <title>Node-RED UI Builder - REACTjs template</title>
    <meta name="description" content="Node-RED UI Builder - REACTjs template">
    <link rel="icon" href="./images/node-blue.ico">

    <link type="text/css" rel="stylesheet" href="./index.css" media="all">

</head><body>
    
    <h1>uibuilder REACTjs Template</h1>
    <p>Based on React in One Minute</p>
    <p>This page demonstrates using React with no build tooling.</p>
    <p>React is loaded as a script tag.</p>

    <!-- We will put our React component inside this div. -->
    <div id="like_button_container"></div>

    <pre id="msg" class="syntax-highlight">Waiting for a message from Node-RED</pre>

    <!-- You need socket.io if using the old client but the new client works fine on its own -->
    <!-- <script src="../uibuilder/vendor/socket.io/socket.io.js"></script> -->
    <!-- <script src="./uibuilderfe.min.js"></script> -->
    <script src="./uibuilder.iife.min.js"></script>
    
    <!-- Load React. -->
    <!-- Note: when deploying, replace "development.js" with "production.min.js". -->
    <script src="https://unpkg.com/react@17/umd/react.development.js" crossorigin></script>
    <script src="https://unpkg.com/react-dom@17/umd/react-dom.development.js" crossorigin></script>

    <script src="./index.js"></script>

</body></html>

index.js

/* jshint browser: true, esversion: 6, asi: true */
/* globals uibuilder */
// @ts-nocheck
'use strict'

/** Minimalist code for uibuilder and Node-RED */

// return formatted HTML version of JSON object
function syntaxHighlight(json) {
    json = JSON.stringify(json, undefined, 4)
    json = json.replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;')
    json = json.replace(/("(\\u[a-zA-Z0-9]{4}|\\[^u]|[^\\"])*"(\s*:)?|\b(true|false|null)\b|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?)/g, function (match) {
        var cls = 'number'
        if (/^"/.test(match)) {
            if (/:$/.test(match)) {
                cls = 'key'
            } else {
                cls = 'string'
            }
        } else if (/true|false/.test(match)) {
            cls = 'boolean'
        } else if (/null/.test(match)) {
            cls = 'null'
        }
        return '<span class="' + cls + '">' + match + '</span>'
    })
    return json
} // --- End of syntaxHighlight --- //

const e = React.createElement

class LikeButton extends React.Component {
  constructor(props) {
    super(props)
    this.state = { liked: false }
  }

  render() {
    if (this.state.liked) {
      return 'You liked this.'
    }

    return e(
      'button',
      { onClick: () => {
          this.setState({ liked: true }) 
          uibuilder.send({payload: {liked: true}})
      }},
      'Like'
    );
  }
}

const domContainer = document.querySelector('#like_button_container')
ReactDOM.render(e(LikeButton), domContainer)


// run this function when the document is loaded
window.onload = function() {
    // Start up uibuilder - not needed with the new client
    // uibuilder.start()

    // Listen for incoming messages from Node-RED
    uibuilder.onChange('msg', function(msg){
        console.info('[indexjs:uibuilder.onChange] msg received from Node-RED server:', msg)

        // dump the msg as text to the "msg" html element
        const eMsg = document.getElementById('msg')
        eMsg.innerHTML = syntaxHighlight(msg)
    })
}
Clone this wiki locally