Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

EWD 3 Training Course Part 37: Building a React.js application with ewd-xpress Part 1

653 views

Published on

This is part 37 of the EWD 3 Training Course. This presentation introduces and and begins to explore how to develop a React.js application that integrates with QEWD

Published in: Software
  • Be the first to comment

EWD 3 Training Course Part 37: Building a React.js application with ewd-xpress Part 1

  1. 1. Copyright © 2016 M/Gateway Developments Ltd EWD 3 Training Course Part 37 Building a React.js-based QEWD Application (a) Getting started Rob Tweed Director, M/Gateway Developments Ltd Twitter: @rtweed
  2. 2. Copyright © 2016 M/Gateway Developments Ltd Assumptions • You understand the basic principles of React.js • If not, try taking this introductory course: – https://www.udemy.com/introduction-to-reactjs • You've installed Node.js and an appropriate database: – Windows or OS X: Caché or GlobalsDB – Linux: Redis, Caché, GlobalsDB or GT.M
  3. 3. Copyright © 2016 M/Gateway Developments Ltd Setting up the React.js Environment • Ensure that you've installed: – QEWD – qewd-monitor – ewd-client • If you haven't done so, here's how: – cd ~/qewd // or wherever you want your QEWD environment – npm install qewd qewd-monitor ewd-client
  4. 4. Copyright © 2016 M/Gateway Developments Ltd If you're using Linux • You can use the QEWD / React installer: cd ~ wget https://raw.githubusercontent.com/robtweed/qewd/master/installers/reactEnvironment.sh source reactEnvironment.sh
  5. 5. Copyright © 2016 M/Gateway Developments Ltd Otherwise do it manually cd ~/qewd npm install react react-dom babelify babel-preset-react react-bootstrap npm install react-toastr react-select socket.io-client npm install jquery ewd-client ewd-react-tools qewd-react npm install -g browserify npm install -g uglify-js
  6. 6. Copyright © 2016 M/Gateway Developments Ltd Create a new application folder cd qewdwww mkdir react-demo1 cd react-demo1 npm install babel-preset-es2015
  7. 7. Copyright © 2016 M/Gateway Developments Ltd Ready to start developing!
  8. 8. Copyright © 2016 M/Gateway Developments Ltd index.html ~/qewd/www/react-demo1/index.html <html xml:lang="en" xmlns="http://www.w3.org/1999/xhtml"> <head> <title id="QEWD React.js Example"></title> </head> <body> <div id="content"></div> <script src="bundle.js"></script> </body> </html>
  9. 9. Copyright © 2016 M/Gateway Developments Ltd app.js ~/qewd/www/react-demo1/app.js var reactLoader = require('qewd-react').loader; var params = { applicationName: 'react-demo1', MainPage: require('./MainPage') }; reactLoader(params);
  10. 10. Copyright © 2016 M/Gateway Developments Ltd MainPage.js c:ewd3wwwreact-demo1MainPage.js "use strict" var React = require('react'); var MainPage = React.createClass({ render: function() { console.log('rendering MainPage'); return ( <div> This is my test React.js Application </div> ); } }); module.exports = MainPage;
  11. 11. Copyright © 2016 M/Gateway Developments Ltd Bundle it cd ~/qewd/www/react-demo1 browserify -t [ babelify --compact false --presets [es2015 react] ] app.js > bundle.js You should now see bundle.js in the ~/qewd/www/react-demo1 folder
  12. 12. Copyright © 2016 M/Gateway Developments Ltd Try it
  13. 13. Copyright © 2016 M/Gateway Developments Ltd So what just happened?
  14. 14. Copyright © 2016 M/Gateway Developments Ltd It's a standard React.js App… • But it has automated: – EWD 3 / ewd-client startup – QEWD application registration • Used qewd-react.loader to do this
  15. 15. Copyright © 2016 M/Gateway Developments Ltd The startup sequence • Explained in an earlier part of the course: – Wait until the browser's DOM is ready – Then invoke EWD.start() • Passing socket.io object as an argument if using web-sockets – When EWD has started • You need to wait until your QEWD application has been registered in the QEWD back-end – Now your application is ready for user interaction
  16. 16. Copyright © 2016 M/Gateway Developments Ltd Doing this in React is more tricky • Must use React's life-cycle methods – If any of these are invoked, DOM is ready • Can therefore start EWD within them – BUT the top-level component will still render while EWD is starting – SO you need two render alternatives, dependent on a state variable's value • 'Please wait' message; or • Render the application's main component – AND • reset the state variable's value when EWD has started and application has been registered • pass EWD object into main component as a prop
  17. 17. Copyright © 2016 M/Gateway Developments Ltd A lot to remember • Need to do all of these things every time you want to start any QEWD application – Lots to remember and potentially go wrong – Ideal candidate for automation • So all this behaviour is pre-written for you in the qewd-react module – Let it do all that startup stuff – You just focus on the main and subsequent modules for your application
  18. 18. Copyright © 2016 M/Gateway Developments Ltd By all means take a look • ~/qewd/node_modules/qewd-react – /lib/loader.js – Uses the componentWillMount() and componentDidMount() lifecycle methods • EWD is started in the latter – Uses a state variable that flips when your application is registered • Causing your main component to render • It's then over to you
  19. 19. Copyright © 2016 M/Gateway Developments Ltd Hierarchy of Components • Your QEWD application must be written as a hierarchy of React components – Each is a self-contained module – Each one will need access to the EWD object • To send messages to the QEWD back-end • To handle responses/messages sent/returned from the QEWD back-end • Components are bundled for use in browser – Using WebPack or Browserify
  20. 20. Copyright © 2016 M/Gateway Developments Ltd We saw this before • See Part 30 of this course (Modularising QEWD Applications) – From around slide 55 • The EWD object must be made available to each module – BUT it must be the post-registration instance of the EWD object • So it has the send() method, etc and session token available
  21. 21. Copyright © 2016 M/Gateway Developments Ltd How's this done with React? Let's look at the render() function in that loader module…
  22. 22. Copyright © 2016 M/Gateway Developments Ltd How's this done with React? render: function render() { var componentPath = ['app']; var renderComponent; if (this.state.status === 'wait') { renderComponent = React.createElement( 'div', null, 'Please wait...' ); } else { renderComponent = React.createElement(MainPage, { controller: this.controller, componentPath: componentPath }); } return renderComponent; } });
  23. 23. Copyright © 2016 M/Gateway Developments Ltd How's this done with React? render: function render() { var componentPath = ['app']; var renderComponent; if (this.state.status === 'wait') { renderComponent = React.createElement( 'div', null, 'Please wait...' ); } else { renderComponent = React.createElement(MainPage, { controller: this.controller, componentPath: componentPath }); } return renderComponent; } }); Here's the "Please wait" message which appears while EWD is starting and application is being registered
  24. 24. Copyright © 2016 M/Gateway Developments Ltd How's this done with React? render: function render() { var componentPath = ['app']; var renderComponent; if (this.state.status === 'wait') { renderComponent = React.createElement( 'div', null, 'Please wait...' ); } else { renderComponent = React.createElement(MainPage, { controller: this.controller, componentPath: componentPath }); } return renderComponent; } }); Here's how it invokes your main component instead, once everything has started
  25. 25. Copyright © 2016 M/Gateway Developments Ltd How's this done with React? render: function render() { var componentPath = ['app']; var renderComponent; if (this.state.status === 'wait') { renderComponent = React.createElement( 'div', null, 'Please wait...' ); } else { renderComponent = React.createElement(MainPage, { controller: this.controller, componentPath: componentPath }); } return renderComponent; } }); Here's how it invokes your main component instead, once everything has started Your main component is referred to as MainPage
  26. 26. Copyright © 2016 M/Gateway Developments Ltd Where's the EWD object? render: function render() { var componentPath = ['app']; var renderComponent; if (this.state.status === 'wait') { renderComponent = React.createElement( 'div', null, 'Please wait...' ); } else { renderComponent = React.createElement(MainPage, { controller: this.controller, componentPath: componentPath }); } return renderComponent; } }); But where is the EWD object?
  27. 27. Copyright © 2016 M/Gateway Developments Ltd Where's the EWD object? render: function render() { var componentPath = ['app']; var renderComponent; if (this.state.status === 'wait') { renderComponent = React.createElement( 'div', null, 'Please wait...' ); } else { renderComponent = React.createElement(MainPage, { controller: this.controller, componentPath: componentPath }); } return renderComponent; } }); This is it
  28. 28. Copyright © 2016 M/Gateway Developments Ltd Where's the EWD object? render: function render() { var componentPath = ['app']; var renderComponent; if (this.state.status === 'wait') { renderComponent = React.createElement( 'div', null, 'Please wait...' ); } else { renderComponent = React.createElement(MainPage, { controller: this.controller, componentPath: componentPath }); } return renderComponent; } }); EWD is part of an object I've called the controller
  29. 29. Copyright © 2016 M/Gateway Developments Ltd Where's the EWD object? render: function render() { var componentPath = ['app']; var renderComponent; if (this.state.status === 'wait') { renderComponent = React.createElement( 'div', null, 'Please wait...' ); } else { renderComponent = React.createElement(MainPage, { controller: this.controller, componentPath: componentPath }); } return renderComponent; } }); EWD is part of an object I've called the controller This object is instantiated for you and passed to your Main module as a prop named controller
  30. 30. Copyright © 2016 M/Gateway Developments Ltd Separation of Concerns • An important principle of modern web application development is separation of concerns – Move away from monolithic programming – Each key aspect of an application is kept separate • Easier to maintain and understand • More scalable as application grows in size
  31. 31. Copyright © 2016 M/Gateway Developments Ltd React focuses on the View • Your React components should just describe the View aspect of your application – What it looks like under various situations as the application is used • The other aspects of your application, commonly referred to as the Model and Controller, should, for best practice, be kept separate from the View
  32. 32. Copyright © 2016 M/Gateway Developments Ltd The controller object • Provides a place to describe the dynamic behaviour that needs to take place in any of your application's React components • The controller object is passed as a prop to any of your components that requires dynamic behaviour
  33. 33. Copyright © 2016 M/Gateway Developments Ltd The controller object • The controller object is initially created for you by the qewd-react loader module and passed to your MainPage module as a prop – You refer to it as this.props.controller – The controller object includes within it the post-registration EWD object • eg this.props.controller.send() allows you to send messages to the QEWD back-end
  34. 34. Copyright © 2016 M/Gateway Developments Ltd The controller object • The idea is for you to extend the controller object in each of your React components to define the behaviour of that component: – Events – Messages to be sent – Responses to be handled – Corresponding changes to state variables within the component • Which cause a re-render of the component and its child components
  35. 35. Copyright © 2016 M/Gateway Developments Ltd Passing on the controller object • qewd-react's loader module creates the controller object for you and passes it to your MainPage component • It's up to you to pass it on to any of your other React components as a prop
  36. 36. Copyright © 2016 M/Gateway Developments Ltd So let's review the demo app
  37. 37. Copyright © 2016 M/Gateway Developments Ltd index.html ~/qewd/www/react-demo1/index.html <html xml:lang="en" xmlns="http://www.w3.org/1999/xhtml"> <head> <title id="QEWD React.js Example"></title> </head> <body> <div id="content"></div> <script src="bundle.js"></script> </body> </html> Place-holder div into which React renders its generated mark-up Your application will be built up from within this div Always give it an id of 'content'
  38. 38. Copyright © 2016 M/Gateway Developments Ltd index.html ~/qewd/www/react-demo1/index.html <html xml:lang="en" xmlns="http://www.w3.org/1999/xhtml"> <head> <title id="ewd-xpress React.js Example"></title> </head> <body> <div id="content"></div> <script src="bundle.js"></script> </body> </html> Load the bundled application's Javascript into the browser You'll use Browserify or WebPack to turn your hierarchy of React Components into a bundle file
  39. 39. Copyright © 2016 M/Gateway Developments Ltd app.js ~/qewd/www/react-demo1/app.js var reactLoader = require('qewd-react').loader; var params = { applicationName: 'react-demo1', MainPage: require('./MainPage') }; reactLoader(params); This is the top level of your React application's hierarchy of modules
  40. 40. Copyright © 2016 M/Gateway Developments Ltd app.js ~/qewd/www/react-demo1/app.js var reactLoader = require('qewd-react').loader; var params = { applicationName: 'react-demo1', MainPage: require('./MainPage') }; reactLoader(params); This is the top level of your React application's hierarchy of modules It makes use of the qewd-react loader to get everything started
  41. 41. Copyright © 2016 M/Gateway Developments Ltd app.js ~/qewd/www/react-demo1/app.js var reactLoader = require('qewd-react').loader; var params = { applicationName: 'react-demo1', MainPage: require('./MainPage') }; reactLoader(params); You just define two things:
  42. 42. Copyright © 2016 M/Gateway Developments Ltd app.js ~/qewd/www/react-demo1/app.js var reactLoader = require('qewd-react').loader; var params = { applicationName: 'react-demo1', MainPage: require('./MainPage') }; reactLoader(params); You just define two things: The application name This is the name that will be used by ewd-xpress to register it
  43. 43. Copyright © 2016 M/Gateway Developments Ltd app.js ~/qewd/www/react-demo1/app.js var reactLoader = require('qewd-react').loader; var params = { applicationName: 'react-demo1', MainPage: require('./MainPage') }; reactLoader(params); You just define two things: Your Application's effective top-level Component Referred to as MainPage but your component file can be named what you like Note: you use require() to load the file
  44. 44. Copyright © 2016 M/Gateway Developments Ltd MainPage.js ~/qewd/www/react-demo1/MainPage.js "use strict" var React = require('react'); var MainPage = React.createClass({ render: function() { console.log('rendering MainPage'); return ( <div> This is my test React.js Application </div> ); } }); module.exports = MainPage; So as far as you're concerned, this is your top component By the time it is invoked, EWD has started and the application is registered by QEWD
  45. 45. Copyright © 2016 M/Gateway Developments Ltd MainPage.js ~/qewd/www/react-demo1/MainPage.js "use strict" var React = require('react'); var MainPage = React.createClass({ render: function() { console.log('rendering MainPage'); return ( <div> This is my test React.js Application </div> ); } }); module.exports = MainPage; Here we're not doing anything except displaying this text
  46. 46. Copyright © 2016 M/Gateway Developments Ltd Then we bundled it cd ~/qewd/www/react-demo1 browserify -t [ babelify --compact false --presets [es2015 react] ] app.js > bundle.js We told Browserify to start with app.js It automatically threads its way down through any require() functions
  47. 47. Copyright © 2016 M/Gateway Developments Ltd Then we bundled it cd ~/qewd/www/react-demo1 browserify -t [ babelify --compact false --presets [es2015 react] ] app.js > bundle.js We told Browserify to start with app.js It automatically threads its way down through any require() functions and combines all the JavaScript into a single file named bundle.js
  48. 48. Copyright © 2016 M/Gateway Developments Ltd So when we start the app ~/qewd/www/react-demo1/index.html <html xml:lang="en" xmlns="http://www.w3.org/1999/xhtml"> <head> <title id="QEWD React.js Example"></title> </head> <body> <div id="content"></div> <script src="bundle.js"></script> </body> </html> The index.html file is loaded into the browser, and it then loads the bundled JavaScript file
  49. 49. Copyright © 2016 M/Gateway Developments Ltd And what we see is…
  50. 50. Copyright © 2016 M/Gateway Developments Ltd And what we see is… The application is registered
  51. 51. Copyright © 2016 M/Gateway Developments Ltd And what we see is… And displays the text defined in your MainPage component
  52. 52. Copyright © 2016 M/Gateway Developments Ltd It's not doing much so far ~/qewd/www/react-demo1/MainPage.js "use strict" var React = require('react'); var MainPage = React.createClass({ render: function() { console.log('rendering MainPage'); return ( <div> This is my test React.js Application </div> ); } }); module.exports = MainPage; We'll start to build it out in the next part of the course
  53. 53. Copyright © 2016 M/Gateway Developments Ltd It's not doing much so far ~/qewd/www/react-demo1/MainPage.js "use strict" var React = require('react'); var MainPage = React.createClass({ render: function() { console.log('rendering MainPage'); return ( <div> This is my test React.js Application </div> ); } }); module.exports = MainPage; We'll make it send a message To QEWD and return a response that we display See the next part of this course

×