ewd 3 training course part 39: building a react.js application with qewd, part 3
TRANSCRIPT
Copyright © 2016 M/Gateway Developments Ltd
EWD 3 Training CoursePart 39
Building a React.js-basedQEWD Application
(c) Separating Concerns
Rob TweedDirector, M/Gateway Developments Ltd
Twitter: @rtweed
Copyright © 2016 M/Gateway Developments Ltd
"use strict"var React = require('react');var displayText = '';var MainPage = React.createClass({
getInitialState: function() {return {
status: 'initial',}
},componentWillMount: function() {
this.props.controller.log = true;var message = {
type: 'testMessage',params: {
foo: 'bar'}
};var component = this;this.props.controller.send(message, function(responseObj) {
displayText = responseObj.message.text;component.setState({status: 'updated'});
});},render: function() {
console.log('rendering MainPage');return (
<div>{displayText}</div>);
}});module.exports = MainPage;
Copyright © 2016 M/Gateway Developments Ltd
Separation of Concerns
• Currently they aren't separated– The dynamic behaviour and its associated
controlling logic is all included in the MainPage component
– MainPage should ideally just describe the View logic
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() {
console.log('rendering MainPage');return (
<div>{this.displayText}</div>);
}});module.exports = MainPage;
MainPage.js
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() {
console.log('rendering MainPage');return (
<div>{this.displayText}</div>);
}});module.exports = MainPage;
MainPage.js
Now describes only theView for our component
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() {
console.log('rendering MainPage');return (
<div>{ this.displayText }</div>);
}});module.exports = MainPage;
MainPage.js
Now describes only theView for our component
displayText is now aproperty of this, nota variable that has tobe instantiated in thecomponent itself
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() {
console.log('rendering MainPage');return (
<div>{this.displayText}</div>);
}});module.exports = MainPage;
MainPage.js
Now describes only theView for our component
Dynamic behaviour isnow described in aseparate module thatwe load into the MainPageComponent here
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() {
console.log('rendering MainPage');return (
<div>{this.displayText}</div>);
}});module.exports = MainPage;
MainPage.js
Now describes only theView for our component
State is still the concernof MainPage, but it's justfor triggering re-renders
Copyright © 2016 M/Gateway Developments Ltd
MainPage-controller.jsmodule.exports = function (controller, component) {// describe the Component's dynamic behaviourreturn controller;
};
Copyright © 2016 M/Gateway Developments Ltd
MainPage-controller.jsmodule.exports = function (controller, component) {// describe the Component's dynamic behaviourreturn controller;
};
Invoked by the parent component like this:
componentWillMount: function() {controller = require('./MainPage-controller')(this.props.controller, this);
},
Copyright © 2016 M/Gateway Developments Ltd
MainPage-controller.jsmodule.exports = function (controller, component) {// describe the Component's dynamic behaviourreturn controller;
};
Invoked by the parent component like this:
componentWillMount: function() {controller = require('./MainPage-controller')(this.props.controller, this);
},
Copyright © 2016 M/Gateway Developments Ltd
MainPage-controller.jsmodule.exports = function (controller, component) {// describe the Component's dynamic behaviourreturn controller;
};
Invoked by the parent component like this:
componentWillMount: function() {controller = require('./MainPage-controller')(this.props.controller, this);
},
Copyright © 2016 M/Gateway Developments Ltd
MainPage-controller.jsmodule.exports = function (controller, component) {// describe the Component's dynamic behaviourreturn controller;
};
Invoked by the parent component like this:
componentWillMount: function() {controller = require('./MainPage-controller')(this.props.controller, this);
},
New augmented instance
Copyright © 2016 M/Gateway Developments Ltd
"use strict"var React = require('react');var displayText = '';var MainPage = React.createClass({
getInitialState: function() {return {
status: 'initial',}
},componentWillMount: function() {
this.props.controller.log = true;var message = {
type: 'testMessage',params: {
foo: 'bar'}
};var component = this;this.props.controller.send(message, function(responseObj) {
displayText = responseObj.message.text;component.setState({status: 'updated'});
});},render: function() {
console.log('rendering MainPage');return (
<div>{displayText}</div>);
}});module.exports = MainPage;
This was our originalComponent's logic
We need to move thecode in red into theController module
Copyright © 2016 M/Gateway Developments Ltd
MainPage-controller.jsmodule.exports = function (controller, component) {component.displayText = '';controller.log = true;var message = {type: 'testMessage',params: {foo: 'bar'
}};
controller.send(message, function(responseObj) {component.displayText = responseObj.message.text;component.setState({status: 'updated'});
});return controller;
};
Copyright © 2016 M/Gateway Developments Ltd
MainPage-controller.jsmodule.exports = function (controller, component) {component.displayText = '';controller.log = true;var message = {type: 'testMessage',params: {foo: 'bar'
}};
controller.send(message, function(responseObj) {component.displayText = responseObj.message.text;component.setState({status: 'updated'});
});return controller;};
Initialising and changingthe value of
this.displayText in theparent component
Copyright © 2016 M/Gateway Developments Ltd
MainPage-controller.jsmodule.exports = function (controller, component) {component.displayText = '';controller.log = true;var message = {type: 'testMessage',params: {foo: 'bar'
}};
controller.send(message, function(responseObj) {component.displayText = responseObj.message.text;component.setState({status: 'updated'});
});return controller;};
Changing the parentcomponent's statevariable value to
trigger a re-render
Copyright © 2016 M/Gateway Developments Ltd
Re-bundle and try it again
It will run exactlythe same as before
Copyright © 2016 M/Gateway Developments Ltd
Pattern for Development• The pattern we've created can be adopted for all of your
components and sub-components• It cleanly separates the concerns:
– View: the parent component– Dynamic behaviour: the controller module
• There are alternatives in the React world:– Flux, Redux, etc– These can also be used with QEWD
• Worth exploring when you're more familiar with the concepts within React
• Let's use the simpler pattern described in this part of the QEWD course for now