Successfully reported this slideshow.
Your SlideShare is downloading. ×

EWD 3 Training Course Part 41: Building a React.js application with QEWD, Part 5

Ad
Ad
Ad
Ad
Ad
Ad
Ad
Ad
Ad
Ad
Ad

Check these out next

1 of 73 Ad

More Related Content

Slideshows for you (20)

Viewers also liked (17)

Advertisement

Similar to EWD 3 Training Course Part 41: Building a React.js application with QEWD, Part 5 (20)

More from Rob Tweed (13)

Advertisement

Recently uploaded (20)

EWD 3 Training Course Part 41: Building a React.js application with QEWD, Part 5

  1. 1. Copyright © 2016 M/Gateway Developments Ltd EWD 3 Training Course Part 41 Building a React.js-based QEWD Application (e) Building out a login sequence Rob Tweed Director, M/Gateway Developments Ltd Twitter: @rtweed
  2. 2. Copyright © 2016 M/Gateway Developments Ltd What We Want to Do
  3. 3. Copyright © 2016 M/Gateway Developments Ltd What We Want to Do
  4. 4. Copyright © 2016 M/Gateway Developments Ltd What We Want to Do
  5. 5. Copyright © 2016 M/Gateway Developments Ltd React.js Design Main Page Title / Banner Login Form Content
  6. 6. Copyright © 2016 M/Gateway Developments Ltd React.js Design Main Page Title / Banner Login Form Content Initially Initial Title Display the form No Content
  7. 7. Copyright © 2016 M/Gateway Developments Ltd React.js Design Main Page Title / Banner Login Form Content On login error Initial Title Display the form No Content Display Error
  8. 8. Copyright © 2016 M/Gateway Developments Ltd React.js Design Main Page Title / Banner Login Form Content On Successful login Hello {{user}} title Hide the form Display Content
  9. 9. Copyright © 2016 M/Gateway Developments Ltd React.js Design Main Page Title / Banner Login Form Content React.js Mechanics Send username & password as EWD message
  10. 10. Copyright © 2016 M/Gateway Developments Ltd React.js Design Main Page Title / Banner Login Form Content React.js Mechanics Send username & password as EWD message To QEWD Back-end
  11. 11. Copyright © 2016 M/Gateway Developments Ltd React.js Design Main Page Title / Banner Login Form Content React.js Mechanics From Back-end Handle response
  12. 12. Copyright © 2016 M/Gateway Developments Ltd React.js Design Main Page Title / Banner Login Form Content React.js Mechanics Error response received: Display Error
  13. 13. Copyright © 2016 M/Gateway Developments Ltd React.js Design Main Page Title / Banner Login Form Content React.js Mechanics Success response received: Re-render
  14. 14. Copyright © 2016 M/Gateway Developments Ltd React.js Design Main Page Title / Banner Login Form Content React.js Mechanics Pass down Username as prop
  15. 15. Copyright © 2016 M/Gateway Developments Ltd React.js Design Main Page Title / Banner Login Form Content React.js Mechanics Pass prop to Signal successful login
  16. 16. Copyright © 2016 M/Gateway Developments Ltd React.js Design Main Page Title / Banner Login Form Content React.js Mechanics Pass prop to signal that content should be displayed
  17. 17. Copyright © 2016 M/Gateway Developments Ltd So let's build out the components In ~/qewd/www/react-demo1
  18. 18. Copyright © 2016 M/Gateway Developments Ltd MainPage.js "use strict" var React = require('react'); var Title = require('./Title'); var Content = require('./Content'); var Login = require('./Login'); var jQuery = require('jquery'); window.$ = window.jQuery = jQuery; var controller; var MainPage = React.createClass({ getInitialState: function() { return { status: 'initial', } }, componentWillMount: function() { controller = require('./MainPage-controller')(this.props.controller, this); }, render: function() { console.log('Rendering MainPage'); return ( <div> <Title controller = {controller} username = {this.username} /> <Login controller = {controller} loggedIn = {this.loggedIn} /> <Content controller = {controller} content = {this.content} /> </div> ); } }); module.exports = MainPage;
  19. 19. Copyright © 2016 M/Gateway Developments Ltd MainPage.js "use strict" var React = require('react'); var Title = require('./Title'); var Content = require('./Content'); var Login = require('./Login'); var jQuery = require('jquery'); window.$ = window.jQuery = jQuery; var controller; var MainPage = React.createClass({ getInitialState: function() { return { status: 'initial', } }, componentWillMount: function() { controller = require('./MainPage-controller')(this.props.controller, this); }, render: function() { console.log('Rendering MainPage'); return ( <div> <Title controller = {controller} username = {this.username} /> <Login controller = {controller} loggedIn = {this.loggedIn} /> <Content controller = {controller} content = {this.content} /> </div> ); } }); module.exports = MainPage; Initial state variable value
  20. 20. Copyright © 2016 M/Gateway Developments Ltd MainPage.js "use strict" var React = require('react'); var Title = require('./Title'); var Content = require('./Content'); var Login = require('./Login'); var jQuery = require('jquery'); window.$ = window.jQuery = jQuery; var controller; var MainPage = React.createClass({ getInitialState: function() { return { status: 'initial', } }, componentWillMount: function() { controller = require('./MainPage-controller')(this.props.controller, this); }, render: function() { console.log('Rendering MainPage'); return ( <div> <Title controller = {controller} username = {this.username} /> <Login controller = {controller} loggedIn = {this.loggedIn} /> <Content controller = {controller} content = {this.content} /> </div> ); } }); module.exports = MainPage; props passed to child components
  21. 21. Copyright © 2016 M/Gateway Developments Ltd MainPage-controller.js module.exports = function (controller, component) { controller.log = true; component.loggedIn = false; component.username = ''; component.content = ''; controller.on('error', function(responseObj) { alert('Error: ' + responseObj.message.error); }); controller.on('login', function(responseObj) { if (!responseObj.message.error) { console.log('Logged in!'); component.loggedIn = true; component.username = responseObj.message.name; component.content = 'User has logged in - ready to display some content for the user!'; component.setState({ status: 'loggedIn' }); } }); return controller; };
  22. 22. Copyright © 2016 M/Gateway Developments Ltd MainPage-controller.js module.exports = function (controller, component) { controller.log = true; component.loggedIn = false; component.username = ''; component.content = ''; controller.on('error', function(responseObj) { alert('Error: ' + responseObj.message.error); }); controller.on('login', function(responseObj) { if (!responseObj.message.error) { console.log('Logged in!'); component.loggedIn = true; component.username = responseObj.message.name; component.content = 'User has logged in - ready to display some content for the user!'; component.setState({ status: 'loggedIn' }); } }); return controller; }; Response from back-end handled in this top component
  23. 23. Copyright © 2016 M/Gateway Developments Ltd MainPage-controller.js module.exports = function (controller, component) { controller.log = true; component.loggedIn = false; component.username = ''; component.content = ''; controller.on('error', function(responseObj) { alert('Error: ' + responseObj.message.error); }); controller.on('login', function(responseObj) { if (!responseObj.message.error) { console.log('Logged in!'); component.loggedIn = true; component.username = responseObj.message.name; component.content = 'User has logged in - ready to display some content for the user!'; component.setState({ status: 'loggedIn' }); } }); return controller; }; Initial values passed as props to child components
  24. 24. Copyright © 2016 M/Gateway Developments Ltd MainPage-controller.js module.exports = function (controller, component) { controller.log = true; component.loggedIn = false; component.username = ''; component.content = ''; controller.on('error', function(responseObj) { alert('Error: ' + responseObj.message.error); }); controller.on('login', function(responseObj) { if (!responseObj.message.error) { console.log('Logged in!'); component.loggedIn = true; component.username = responseObj.message.name; component.content = 'User has logged in - ready to display some content for the user!'; component.setState({ status: 'loggedIn' }); } }); return controller; }; New values passed as props to child components if login is successful
  25. 25. Copyright © 2016 M/Gateway Developments Ltd MainPage-controller.js module.exports = function (controller, component) { controller.log = true; component.loggedIn = false; component.username = ''; component.content = ''; controller.on('error', function(responseObj) { alert('Error: ' + responseObj.message.error); }); controller.on('login', function(responseObj) { if (!responseObj.message.error) { console.log('Logged in!'); component.loggedIn = true; component.username = responseObj.message.name; component.content = 'User has logged in - ready to display some content for the user!'; component.setState({ status: 'loggedIn' }); } }); return controller; }; State value changed to trigger re-render of this component and its child components
  26. 26. Copyright © 2016 M/Gateway Developments Ltd Title.js var React = require('react'); var controller; var Title = React.createClass({ componentWillMount: function() { controller = require('./Title-controller')(this.props.controller, this); }, componentWillReceiveProps: function(newProps) { this.updateHeading(newProps.username); }, render: function() { console.log('Rendering Title'); return ( <h2> {this.heading} </h2> ); } }); module.exports = Title;
  27. 27. Copyright © 2016 M/Gateway Developments Ltd Title.js var React = require('react'); var controller; var Title = React.createClass({ componentWillMount: function() { controller = require('./Title-controller')(this.props.controller, this); }, componentWillReceiveProps: function(newProps) { this.updateHeading(newProps.username); }, render: function() { console.log('Rendering Title'); return ( <h2> {this.heading} </h2> ); } }); module.exports = Title; Fires if props have changed Does not fire on initial render
  28. 28. Copyright © 2016 M/Gateway Developments Ltd Title-controller.js module.exports = function (controller, component) { component.heading = 'My QEWD React Demo'; component.updateHeading = function(username) { if (username !== '') { component.heading = 'Welcome, ' + username + ', to ' + component.heading; } }; return controller; };
  29. 29. Copyright © 2016 M/Gateway Developments Ltd Login.js"use strict" var React = require('react'); var controller; var Login = React.createClass({ getInitialState: function() { return { status: 'initial', } }, componentWillMount: function() { controller = require('./Login-controller')(this.props.controller, this); }, render: function() { console.log('rendering Login'); if (this.props.loggedIn) { return ( <div></div> ); } return ( <table id="loginTable"> <tbody> <tr> <td>Username: </td> <td><input id="username" /> </td> </tr> <tr> <td>Password: </td> <td><input id="password" type="password" /> </td> </tr> <tr> <td colSpan="2"> <button id="LoginBtn" onClick={this.LoginBtnClicked} > Login </button> </td> </tr> </tbody> </table> ); } }); module.exports = Login;
  30. 30. Copyright © 2016 M/Gateway Developments Ltd Login.js"use strict" var React = require('react'); var controller; var Login = React.createClass({ getInitialState: function() { return { status: 'initial', } }, componentWillMount: function() { controller = require('./Login-controller')(this.props.controller, this); }, render: function() { console.log('rendering Login'); if (this.props.loggedIn) { return ( <div></div> ); } return ( <table id="loginTable"> <tbody> <tr> <td>Username: </td> <td><input id="username" /> </td> </tr> <tr> <td>Password: </td> <td><input id="password" type="password" /> </td> </tr> <tr> <td colSpan="2"> <button id="LoginBtn" onClick={this.LoginBtnClicked} > Login </button> </td> </tr> </tbody> </table> ); } }); module.exports = Login; On successful login, display nothing Form disappears
  31. 31. Copyright © 2016 M/Gateway Developments Ltd Login.js"use strict" var React = require('react'); var controller; var Login = React.createClass({ getInitialState: function() { return { status: 'initial', } }, componentWillMount: function() { controller = require('./Login-controller')(this.props.controller, this); }, render: function() { console.log('rendering Login'); if (this.props.loggedIn) { return ( <div></div> ); } return ( <table id="loginTable"> <tbody> <tr> <td>Username: </td> <td><input id="username" /> </td> </tr> <tr> <td>Password: </td> <td><input id="password" type="password" /> </td> </tr> <tr> <td colSpan="2"> <button id="LoginBtn" onClick={this.LoginBtnClicked} > Login </button> </td> </tr> </tbody> </table> ); } }); module.exports = Login; Otherwise, display the form
  32. 32. Copyright © 2016 M/Gateway Developments Ltd Login.js"use strict" var React = require('react'); var controller; var Login = React.createClass({ getInitialState: function() { return { status: 'initial', } }, componentWillMount: function() { controller = require('./Login-controller')(this.props.controller, this); }, render: function() { console.log('rendering Login'); if (this.props.loggedIn) { return ( <div></div> ); } return ( <table id="loginTable"> <tbody> <tr> <td>Username: </td> <td><input id="username" /> </td> </tr> <tr> <td>Password: </td> <td><input id="password" type="password" /> </td> </tr> <tr> <td colSpan="2"> <button id="LoginBtn" onClick={this.LoginBtnClicked} > Login </button> </td> </tr> </tbody> </table> ); } }); module.exports = Login; JSX Click handler
  33. 33. Copyright © 2016 M/Gateway Developments Ltd Login-controller.js module.exports = function (controller, component) { component.LoginBtnClicked = function(e) { var username = $('#username').val(); var password = $('#password').val(); if (username === '') { alert('You must enter a username!'); return; } if (password === '') { alert('You must enter a password!'); return; } controller.send({ type: 'login', params: { username: username, password: password } }); }; return controller; };
  34. 34. Copyright © 2016 M/Gateway Developments Ltd Login-controller.js module.exports = function (controller, component) { component.LoginBtnClicked = function(e) { var username = $('#username').val(); var password = $('#password').val(); if (username === '') { alert('You must enter a username!'); return; } if (password === '') { alert('You must enter a password!'); return; } controller.send({ type: 'login', params: { username: username, password: password } }); }; return controller; }; Define the Login button's click handler
  35. 35. Copyright © 2016 M/Gateway Developments Ltd Login-controller.js module.exports = function (controller, component) { component.LoginBtnClicked = function(e) { var username = $('#username').val(); var password = $('#password').val(); if (username === '') { alert('You must enter a username!'); return; } if (password === '') { alert('You must enter a password!'); return; } controller.send({ type: 'login', params: { username: username, password: password } }); }; return controller; }; Send the username and password to the ewd-xpress Back-end The response is handled in the Parent component
  36. 36. Copyright © 2016 M/Gateway Developments Ltd Content.js var React = require('react'); var controller; var Content = React.createClass({ componentWillMount: function() { controller = require('./Content-controller')(this.props.controller, this); }, componentWillReceiveProps: function(newProps) { this.updateContent(newProps.content); }, render: function() { console.log('Rendering Content'); return ( <div> {this.content} </div> ); } }); module.exports = Content;
  37. 37. Copyright © 2016 M/Gateway Developments Ltd Content.js var React = require('react'); var controller; var Content = React.createClass({ componentWillMount: function() { controller = require('./Content-controller')(this.props.controller, this); }, componentWillReceiveProps: function(newProps) { this.updateContent(newProps.content); }, render: function() { console.log('Rendering Content'); return ( <div> {this.content} </div> ); } }); module.exports = Content; Simply display the value of this.content each Time it renders
  38. 38. Copyright © 2016 M/Gateway Developments Ltd Content.js var React = require('react'); var controller; var Content = React.createClass({ componentWillMount: function() { controller = require('./Content-controller')(this.props.controller, this); }, componentWillReceiveProps: function(newProps) { this.updateContent(newProps.content); }, render: function() { console.log('Rendering Content'); return ( <div> {this.content} </div> ); } }); module.exports = Content; Use the componentWillReceiveProps life-cycle method to update the content whenever re-rendering occurs
  39. 39. Copyright © 2016 M/Gateway Developments Ltd Content.js var React = require('react'); var controller; var Content = React.createClass({ componentWillMount: function() { controller = require('./Content-controller')(this.props.controller, this); }, componentWillReceiveProps: function(newProps) { this.updateContent(newProps.content); }, render: function() { console.log('Rendering Content'); return ( <div> {this.content} </div> ); } }); module.exports = Content; The componentWillReceiveProps life-cycle method will invoke a method named this.updateContent We'll define it in the content-controller module
  40. 40. Copyright © 2016 M/Gateway Developments Ltd Content-controller.js module.exports = function (controller, component) { component.content = component.props.content; component.updateContent = function(newContent) { if (newContent !== '') { component.content = newContent; } }; return controller; };
  41. 41. Copyright © 2016 M/Gateway Developments Ltd Content-controller.js module.exports = function (controller, component) { component.content = component.props.content; component.updateContent = function(newContent) { if (newContent !== '') { component.content = newContent; } }; return controller; }; Here's the this.updateContent Method It just updates this.content Within the controller, instead of this we refer to component
  42. 42. Copyright © 2016 M/Gateway Developments Ltd Finally the back-end Module • This must handle the login message that is sent from the browser when the Login form button is clicked • It must validate the username and password • For simplicity, we'll just hard-code the valid values – In a real-world app, you'd authenticate against a database or using a dedicated API
  43. 43. Copyright © 2016 M/Gateway Developments Ltd Finally the back-end Module • It's advisable to repeat any browser-side validation at the back-end – A malicious user might attempt to send a login message via the JavaScript console • We'll authenticate the user and prevent an already-logged in user from logging in again
  44. 44. Copyright © 2016 M/Gateway Developments Ltd Back-end module module.exports = { handlers: { login: function(messageObj, session, send, finished) { if (session.authenticated) { finished({error: 'You have already logged in'}); return; } if (messageObj.params.username === '') { finished({error: 'You must enter a username'}); return; } if (messageObj.params.password === '') { finished({error: 'You must enter a password'}); return; } if (messageObj.params.username !== 'rob') { finished({error: 'Invalid username'}); return; } if (messageObj.params.password !== 'secret') { finished({error: 'Invalid password'}); return; } session.authenticated = true; finished({ ok: true, name: 'Rob' }); } } }; ~/qewd/node_modules/react-demo1.js
  45. 45. Copyright © 2016 M/Gateway Developments Ltd Back-end module module.exports = { handlers: { login: function(messageObj, session, send, finished) { if (session.authenticated) { finished({error: 'You have already logged in'}); return; } if (messageObj.params.username === '') { finished({error: 'You must enter a username'}); return; } if (messageObj.params.password === '') { finished({error: 'You must enter a password'}); return; } if (messageObj.params.username !== 'rob') { finished({error: 'Invalid username'}); return; } if (messageObj.params.password !== 'secret') { finished({error: 'Invalid password'}); return; } session.authenticated = true; finished({ ok: true, name: 'Rob' }); } } }; ~/qewd/node_modules/react-demo1.js Repeat the Browser-side Validation Return an error object if it fails
  46. 46. Copyright © 2016 M/Gateway Developments Ltd Back-end module module.exports = { handlers: { login: function(messageObj, session, send, finished) { if (session.authenticated) { finished({error: 'You have already logged in'}); return; } if (messageObj.params.username === '') { finished({error: 'You must enter a username'}); return; } if (messageObj.params.password === '') { finished({error: 'You must enter a password'}); return; } if (messageObj.params.username !== 'rob') { finished({error: 'Invalid username'}); return; } if (messageObj.params.password !== 'secret') { finished({error: 'Invalid password'}); return; } session.authenticated = true; finished({ ok: true, name: 'Rob' }); } } }; ~/qewd/node_modules/react-demo1.js Here's our simple hard-coded validation Username must be 'rob' and password must be 'secret'
  47. 47. Copyright © 2016 M/Gateway Developments Ltd Back-end module module.exports = { handlers: { login: function(messageObj, session, send, finished) { if (session.authenticated) { finished({error: 'You have already logged in'}); return; } if (messageObj.params.username === '') { finished({error: 'You must enter a username'}); return; } if (messageObj.params.password === '') { finished({error: 'You must enter a password'}); return; } if (messageObj.params.username !== 'rob') { finished({error: 'Invalid username'}); return; } if (messageObj.params.password !== 'secret') { finished({error: 'Invalid password'}); return; } session.authenticated = true; finished({ ok: true, name: 'Rob' }); } } }; ~/qewd/node_modules/react-demo1.js Set the session authenticated property
  48. 48. Copyright © 2016 M/Gateway Developments Ltd Back-end module module.exports = { handlers: { login: function(messageObj, session, send, finished) { if (session.authenticated) { finished({error: 'You have already logged in'}); return; } if (messageObj.params.username === '') { finished({error: 'You must enter a username'}); return; } if (messageObj.params.password === '') { finished({error: 'You must enter a password'}); return; } if (messageObj.params.username !== 'rob') { finished({error: 'Invalid username'}); return; } if (messageObj.params.password !== 'secret') { finished({error: 'Invalid password'}); return; } session.authenticated = true; finished({ ok: true, name: 'Rob' }); } } }; ~/qewd/node_modules/react-demo1.js Return a user name in the response object This simple example uses a hard-coded value: 'Rob'
  49. 49. Copyright © 2016 M/Gateway Developments Ltd That should be it! • Re-bundle it using Browserify in the normal way • Try running it!
  50. 50. Copyright © 2016 M/Gateway Developments Ltd Try it
  51. 51. Copyright © 2016 M/Gateway Developments Ltd React.js Design Main Page Title / Banner Login Form Content Initially Initial Title Display the form No Content
  52. 52. Copyright © 2016 M/Gateway Developments Ltd Login with wrong credentials
  53. 53. Copyright © 2016 M/Gateway Developments Ltd React.js Design Main Page Title / Banner Login Form Content On login error Initial Title Display the form No Content Display Error
  54. 54. Copyright © 2016 M/Gateway Developments Ltd Successful login Username: rob ; password: secret
  55. 55. Copyright © 2016 M/Gateway Developments Ltd React.js Design Main Page Title / Banner Login Form Content On Successful login Hello {{user}} title Hide the form Display Content
  56. 56. Copyright © 2016 M/Gateway Developments Ltd How that happened
  57. 57. Copyright © 2016 M/Gateway Developments Ltd React.js Design Main Page Title / Banner Login Form Content React.js Mechanics Send username & password as EWD message
  58. 58. Copyright © 2016 M/Gateway Developments Ltd Login-controller.js module.exports = function (controller, component) { component.LoginBtnClicked = function(e) { var username = $('#username').val(); var password = $('#password').val(); if (username === '') { alert('You must enter a username!'); return; } if (password === '') { alert('You must enter a password!'); return; } controller.send({ type: 'login', params: { username: username, password: password } }); }; return controller; }; Define the Login button's click handler
  59. 59. Copyright © 2016 M/Gateway Developments Ltd Login-controller.js module.exports = function (controller, component) { component.LoginBtnClicked = function(e) { var username = $('#username').val(); var password = $('#password').val(); if (username === '') { alert('You must enter a username!'); return; } if (password === '') { alert('You must enter a password!'); return; } controller.send({ type: 'login', params: { username: username, password: password } }); }; return controller; }; Send the username and password to the ewd-xpress Back-end The response is handled in the Parent component
  60. 60. Copyright © 2016 M/Gateway Developments Ltd React.js Design Main Page Title / Banner Login Form Content React.js Mechanics Send username & password as EWD message To Back-end module: react-demo1.js
  61. 61. Copyright © 2016 M/Gateway Developments Ltd Back-end module module.exports = { handlers: { login: function(messageObj, session, send, finished) { if (session.authenticated) { finished({error: 'You have already logged in'}); return; } if (messageObj.params.username === '') { finished({error: 'You must enter a username'}); return; } if (messageObj.params.password === '') { finished({error: 'You must enter a password'}); return; } if (messageObj.params.username !== 'rob') { finished({error: 'Invalid username'}); return; } if (messageObj.params.password !== 'secret') { finished({error: 'Invalid password'}); return; } session.authenticated = true; finished({ ok: true, name: 'Rob' }); } } }; ~/qewd/node_modules/react-demo1.js Here's our simple hard-coded validation Username must be 'rob' and password must be 'secret'
  62. 62. Copyright © 2016 M/Gateway Developments Ltd React.js Design Main Page Title / Banner Login Form Content React.js Mechanics From Back-end Handle response
  63. 63. Copyright © 2016 M/Gateway Developments Ltd MainPage-controller.js module.exports = function (controller, component) { controller.log = true; component.loggedIn = false; component.username = ''; component.content = ''; controller.on('error', function(responseObj) { alert('Error: ' + responseObj.message.error); }); controller.on('login', function(responseObj) { if (!responseObj.message.error) { console.log('Logged in!'); component.loggedIn = true; component.username = responseObj.message.name; component.content = 'User has logged in - ready to display some content for the user!'; component.setState({ status: 'loggedIn' }); } }); return controller; }; error handler displays alerts
  64. 64. Copyright © 2016 M/Gateway Developments Ltd React.js Design Main Page Title / Banner Login Form Content React.js Mechanics Error response received: Display Error
  65. 65. Copyright © 2016 M/Gateway Developments Ltd MainPage-controller.js module.exports = function (controller, component) { controller.log = true; component.loggedIn = false; component.username = ''; component.content = ''; controller.on('error', function(responseObj) { alert('Error: ' + responseObj.message.error); }); controller.on('login', function(responseObj) { if (!responseObj.message.error) { console.log('Logged in!'); component.loggedIn = true; component.username = responseObj.message.name; component.content = 'User has logged in - ready to display some content for the user!'; component.setState({ status: 'loggedIn' }); } }); return controller; }; login handler deals with successful logins
  66. 66. Copyright © 2016 M/Gateway Developments Ltd MainPage-controller.js module.exports = function (controller, component) { controller.log = true; component.loggedIn = false; component.username = ''; component.content = ''; controller.on('error', function(responseObj) { alert('Error: ' + responseObj.message.error); }); controller.on('login', function(responseObj) { if (!responseObj.message.error) { console.log('Logged in!'); component.loggedIn = true; component.username = responseObj.message.name; component.content = 'User has logged in - ready to display some content for the user!'; component.setState({ status: 'loggedIn' }); } }); return controller; }; New values passed as props to child components if login is successful
  67. 67. Copyright © 2016 M/Gateway Developments Ltd MainPage-controller.js module.exports = function (controller, component) { controller.log = true; component.loggedIn = false; component.username = ''; component.content = ''; controller.on('error', function(responseObj) { alert('Error: ' + responseObj.message.error); }); controller.on('login', function(responseObj) { if (!responseObj.message.error) { console.log('Logged in!'); component.loggedIn = true; component.username = responseObj.message.name; component.content = 'User has logged in - ready to display some content for the user!'; component.setState({ status: 'loggedIn' }); } }); return controller; }; State value changed to trigger re-render of this component and its child components
  68. 68. Copyright © 2016 M/Gateway Developments Ltd React.js Design Main Page Title / Banner Login Form Content React.js Mechanics Success response received: Re-render
  69. 69. Copyright © 2016 M/Gateway Developments Ltd MainPage.js "use strict" var React = require('react'); var Title = require('./Title'); var Content = require('./Content'); var Login = require('./Login'); var jQuery = require('jquery'); window.$ = window.jQuery = jQuery; var controller; var MainPage = React.createClass({ getInitialState: function() { return { status: 'initial', } }, componentWillMount: function() { controller = require('./MainPage-controller')(this.props.controller, this); }, render: function() { console.log('Rendering MainPage'); return ( <div> <Title controller = {controller} username = {this.username} /> <Login controller = {controller} loggedIn = {this.loggedIn} /> <Content controller = {controller} content = {this.content} /> </div> ); } }); module.exports = MainPage; props passed to child components
  70. 70. Copyright © 2016 M/Gateway Developments Ltd React.js Design Main Page Title / Banner Login Form Content React.js Mechanics Pass down Username as prop
  71. 71. Copyright © 2016 M/Gateway Developments Ltd React.js Design Main Page Title / Banner Login Form Content React.js Mechanics Pass prop to Signal successful login
  72. 72. Copyright © 2016 M/Gateway Developments Ltd React.js Design Main Page Title / Banner Login Form Content React.js Mechanics Pass prop to signal that content should be displayed
  73. 73. Copyright © 2016 M/Gateway Developments Ltd And so we have a working demo! Username: rob ; password: secret

×