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 38: Building a React.js application with QEWD, Part 4

325 views

Published on

This is part 38 of the EWD 3 Training Course. This presentation continues to explore how to develop a React.js application that integrates with QEWD

Published in: Software
  • Be the first to comment

  • Be the first to like this

EWD 3 Training Course Part 38: Building a React.js application with QEWD, Part 4

  1. 1. Copyright © 2016 M/Gateway Developments Ltd EWD 3 Training Course Part 40 Building a React.js-based QEWD Application (d) Using sub-components Rob Tweed Director, M/Gateway Developments Ltd Twitter: @rtweed
  2. 2. Copyright © 2016 M/Gateway Developments Ltd Still a very simple app • Our demo doesn't do very much • Just a single top-level component – MainPage.js • Plus its associated controller module • React.js apps are usually a hierarchy of components – Let's start extending our demo
  3. 3. Copyright © 2016 M/Gateway Developments Ltd A More Typical Scenario Main Page Title / Banner Login Form Main Menu Content
  4. 4. Copyright © 2016 M/Gateway Developments Ltd "use strict" var React = require('react'); var controller; var MainPage = React.createClass({ getInitialState: function() { return { status: 'initial', } }, componentWillMount: function() { controller = require('./MainPage-controller')(this.props.controller, this); }, render: function() { return ( // sub-component to handle the Title / banner // sub-component to handle a log-in form // sub-component to handle a main menu // sub-component to handle the main display of content ); } }); module.exports = MainPage; MainPage.js How it would be implemented:
  5. 5. Copyright © 2016 M/Gateway Developments Ltd "use strict" var React = require('react'); var controller; var MainPage = React.createClass({ getInitialState: function() { return { status: 'initial', } }, componentWillMount: function() { controller = require('./MainPage-controller')(this.props.controller, this); }, return ( // sub-component to handle the Title / banner // sub-component to handle the main display of content ); }); module.exports = MainPage; MainPage.js Let's just take 2 for now to keep it simple:
  6. 6. Copyright © 2016 M/Gateway Developments Ltd "use strict" var React = require('react'); var controller; var MainPage = React.createClass({ getInitialState: function() { return { status: 'initial', } }, componentWillMount: function() { controller = require('./MainPage-controller')(this.props.controller, this); }, render: function() { return ( <Title /> <Content /> ); } }); module.exports = MainPage; MainPage.js Let's just take 2 for now to keep it simple:
  7. 7. Copyright © 2016 M/Gateway Developments Ltd "use strict" var React = require('react'); var controller; var Title = require('./Title'); var Content = require('./Content'); var MainPage = React.createClass({ getInitialState: function() { return { status: 'initial', } }, componentWillMount: function() { controller = require('./MainPage-controller')(this.props.controller, this); }, render: function() { return ( <Title /> <Content /> ); } }); module.exports = MainPage; MainPage.js These must be loaded as modules
  8. 8. Copyright © 2016 M/Gateway Developments Ltd "use strict" var React = require('react'); var controller; var Title = require('./Title'); var Content = require('./Content'); var MainPage = React.createClass({ getInitialState: function() { return { status: 'initial', } }, componentWillMount: function() { controller = require('./MainPage-controller')(this.props.controller, this); }, render: function() { return ( <Title controller = {controller} /> <Content controller = {controller} /> ); } }); module.exports = MainPage; MainPage.js We need to pass the controller object into them:
  9. 9. Copyright © 2016 M/Gateway Developments Ltd "use strict" var React = require('react'); var controller; var Title = require('./Title'); var Content = require('./Content'); var MainPage = React.createClass({ getInitialState: function() { return { status: 'initial', } }, componentWillMount: function() { controller = require('./MainPage-controller')(this.props.controller, this); }, render: function() { return ( <Title controller = {controller} /> <Content controller = {controller} /> ); } }); module.exports = MainPage; MainPage.js The child components are now going to do the work The Main Page will no longer have any dynamic behaviour as such, but we'll leave the controller in place, but simplify it
  10. 10. Copyright © 2016 M/Gateway Developments Ltd MainPage-controller.js module.exports = function (controller, component) { controller.log = true; return controller; };
  11. 11. Copyright © 2016 M/Gateway Developments Ltd "use strict" var React = require('react'); var controller; var Title = require('./Title'); var Content = require('./Content'); var MainPage = React.createClass({ getInitialState: function() { return { status: 'initial', } }, componentWillMount: function() { controller = require('./MainPage-controller')(this.props.controller, this); }, render: function() { return ( <Title controller = {controller} /> <Content controller = {controller} /> ); } }); module.exports = MainPage; MainPage.js We'll also leave this state variable in place It might come in useful later
  12. 12. Copyright © 2016 M/Gateway Developments Ltd "use strict" var React = require('react'); var controller; var Title = require('./Title'); var MainPage = React.createClass({ getInitialState: function() { return { status: 'initial', } }, componentWillMount: function() { controller = require('./MainPage-controller')(this.props.controller, this); }, render: function() { return ( <Title controller = {controller} /> ); } }); module.exports = MainPage; MainPage.js So let's create The first Sub-component: <Title />
  13. 13. Copyright © 2016 M/Gateway Developments Ltd <Title /> Component var React = require('react'); var heading = 'My QEWD React Demo'; var Title = React.createClass({ render: function() { return ( <h2> {heading} </h2> ); } }); module.exports = Title;
  14. 14. Copyright © 2016 M/Gateway Developments Ltd <Title /> Component var React = require('react'); var heading = 'My QEWD React Demo'; var Title = React.createClass({ render: function() { return ( <h2> {heading} </h2> ); } }); module.exports = Title; This doesn't require the controller object for its current behaviour
  15. 15. Copyright © 2016 M/Gateway Developments Ltd "use strict" var React = require('react'); var controller; var Title = require('./Title'); var MainPage = React.createClass({ getInitialState: function() { return { status: 'initial', } }, componentWillMount: function() { controller = require('./MainPage-controller')(this.props.controller, this); }, render: function() { return ( <Title controller = {controller} /> ); } }); module.exports = MainPage; MainPage.js But we'll still pass in the controller for now. We might need it later
  16. 16. Copyright © 2016 M/Gateway Developments Ltd <Title /> Component var React = require('react'); var heading = 'My QEWD React Demo'; var Title = React.createClass({ render: function() { return ( <h2> {heading} </h2> ); } }); module.exports = Title; If we did want to use it, it would be referenced as this.props.controller
  17. 17. Copyright © 2016 M/Gateway Developments Ltd <Title /> Component var React = require('react'); var heading = 'My QEWD React Demo'; var Title = React.createClass({ render: function() { return ( <h2> {heading} </h2> ); } }); module.exports = Title; Save as: ~/qewd/www/react-demo1/Title.js
  18. 18. Copyright © 2016 M/Gateway Developments Ltd Re-bundle and try it again
  19. 19. Copyright © 2016 M/Gateway Developments Ltd Now let's add the Content Component
  20. 20. Copyright © 2016 M/Gateway Developments Ltd "use strict" var React = require('react'); var controller; var Title = require('./Title'); var Content = require('./Content'); var MainPage = React.createClass({ getInitialState: function() { return { status: 'initial', } }, componentWillMount: function() { controller = require('./MainPage-controller')(this.props.controller, this); }, render: function() { return ( <Title controller = {controller} /> <Content controller = {controller} /> ); } }); module.exports = MainPage; MainPage.js Add the Content Component…
  21. 21. Copyright © 2016 M/Gateway Developments Ltd <Content /> Component var React = require('react'); var Content = React.createClass({ render: function() { return ( <div> Content will go here... </div> ); } }); module.exports = Content; We'll keep it very simple for now No dynamic behaviour yet
  22. 22. Copyright © 2016 M/Gateway Developments Ltd <Content /> Component var React = require('react'); var Content = React.createClass({ render: function() { return ( <div> Content will go here... </div> ); } }); module.exports = Content; Save as: C:ewd3wwwreact-demo1Content.js
  23. 23. Copyright © 2016 M/Gateway Developments Ltd Re-bundle it cd ewd3wwwreact-demo1 browserify -t [ babelify --compact false --presets [es2015 react] ] app.js > bundle.js
  24. 24. Copyright © 2016 M/Gateway Developments Ltd You'll get an error! [es2015 react] ] app.js > bundle.js SyntaxError: C:/ewd3-react/www/react-demo3/MainPage.js: Adjacent JSX elements mu st be wrapped in an enclosing tag (21:6) 19 | controller = {controller} 20 | /> > 21 | <Content | ^ 22 | controller = {controller} 23 | /> 24 | ); at Parser.pp.raise (C:ewd3-reactnode_modulesbabelifynode_modulesbabel-c orenode_modulesbabylonlibparserlocation.js:22:13) at Parser.pp.jsxParseElementAt (C:ewd3-reactnode_modulesbabelifynode_mod ulesbabel-corenode_modulesbabylonlibpluginsjsxindex.js:470:10)
  25. 25. Copyright © 2016 M/Gateway Developments Ltd You'll get an error! [es2015 react] ] app.js > bundle.js SyntaxError: C:/ewd3-react/www/react-demo3/MainPage.js: Adjacent JSX elements mu st be wrapped in an enclosing tag (21:6) 19 | controller = {controller} 20 | /> > 21 | <Content | ^ 22 | controller = {controller} 23 | /> 24 | ); at Parser.pp.raise (C:ewd3-reactnode_modulesbabelifynode_modulesbabel-c orenode_modulesbabylonlibparserlocation.js:22:13) at Parser.pp.jsxParseElementAt (C:ewd3-reactnode_modulesbabelifynode_mod ulesbabel-corenode_modulesbabylonlibpluginsjsxindex.js:470:10)
  26. 26. Copyright © 2016 M/Gateway Developments Ltd "use strict" var React = require('react'); var controller; var Title = require('./Title'); var Content = require('./Content'); var MainPage = React.createClass({ getInitialState: function() { return { status: 'initial', } }, componentWillMount: function() { controller = require('./MainPage-controller')(this.props.controller, this); }, render: function() { return ( <Title controller = {controller} /> <Content controller = {controller} /> ); } }); module.exports = MainPage; Check in MainPage.js What's inside the return must only be a single parent JSX tag
  27. 27. Copyright © 2016 M/Gateway Developments Ltd "use strict" var React = require('react'); var controller; var Title = require('./Title'); var Content = require('./Content'); var MainPage = React.createClass({ getInitialState: function() { return { status: 'initial', } }, componentWillMount: function() { controller = require('./MainPage-controller')(this.props.controller, this); }, render: function() { return ( <Title controller = {controller} /> <Content controller = {controller} /> ); } }); module.exports = MainPage; Check in MainPage.js What's inside the return must only be a single parent JSX tag So we must put <Title> and <Content> inside a parent tag
  28. 28. Copyright © 2016 M/Gateway Developments Ltd "use strict" var React = require('react'); var controller; var Title = require('./Title'); var Content = require('./Content'); var MainPage = React.createClass({ getInitialState: function() { return { status: 'initial', } }, componentWillMount: function() { controller = require('./MainPage-controller')(this.props.controller, this); }, render: function() { return ( <div> <Title controller = {controller} /> <Content controller = {controller} /> </div> ); } }); module.exports = MainPage; Check in MainPage.js A <div> tag will do the job!
  29. 29. Copyright © 2016 M/Gateway Developments Ltd Now it should re-bundle OK cd ewd3wwwreact-demo1 browserify -t [ babelify --compact false --presets [es2015 react] ] app.js > bundle.js
  30. 30. Copyright © 2016 M/Gateway Developments Ltd Try it again And now we have our two components working properly
  31. 31. Copyright © 2016 M/Gateway Developments Ltd Still just a simple app • No dynamic behaviour • Not using the QEWD back-end • But we've now established the basic patterns for React development with QEWD – The components we've created can be used as convenient templates • In the next part of the course, we'll add some dynamic behaviour

×