SlideShare a Scribd company logo
Adding a Modern Twist to
Legacy Web Applications
Process, Toolset and Buy In
by Jeff Dutra - @JeffDutraCanada
Housekeeping
All the code will be on GitHub
 https://github.com/jefferydutra/AddingModernTwistToLegacyApps
Who Am I
o It does not really matter
o Not an Authority
Who Am I
o software developer/amateur
skeptic/pretend psychologist
o Proficient Web Developer
working towards becoming
an Expert
Introduction
 Manage dependencies and build your JavaScript with Node.js, Gulp, Browserify
 Adding modern web functionality with React and Flux
 Strategies for Buy In to start using these toolsets now (or in some reasonable amount of time)
But Why?
 Avoid misery of working with legacy code
 We will see how you can add independent and isolated
components to existing pages; pages that may be difficult to
change
 React and Flux allow you to make self-contained additions that
handle their own data access/persistence
Go Time
GULP
&
JSHINT
What is Gulp
• Grabs some files
• Modify them
• Output new files
A build system should
only handle basic
functionality and allow
other libraries to do
things they are made to
do.
Why build with
Gulp?
o Minify
o Concatenate
o JSHint
o Compile LESS or
SASS
o Run your tests (now
there is no excuse
when it comes to
writing tests)
Why not Grunt
o Code over
configuration
o Grunt tries do
everything itself
o Gulp relies on an
eco-system of
plug-ins
o Faster
o Cooler logo
The 4 functions
Gulp provides
o gulp.task(name[, deps], fn)
o gulp.src(globs[, options])
o gulp.dest(path[, options])
o gulp.watch(glob[, opts],
tasks)
globs are a pattern or an array of patterns for file matching.
**/*.js = find all files that end in .js
JSHint Task
var gulp = require('gulp');
var jshint = require('gulp-jshint');
var stylish = require('jshint-stylish');
var notify = require("gulp-notify");
gulp.task('jshint', function () {
return gulp.src("./js/library/src/**/*.js")
.pipe(jshint('.jshintrc'))
.pipe(jshint.reporter(stylish))
.pipe(notify(function (file) {
if (file.jshint.success) {
// Don't show something if success
return false;
}
var errors = file.jshint.results.map(function (data) {
if (data.error) {
return "(" + data.error.line + ':' + data.error.character + ') ' +
data.error.reason;
}
}).join("n");
return file.relative + " (" + file.jshint.results.length + " errors)n" + errors;
}));
Adding a modern twist to legacy web applications
JsHint Task Demo
(using AirBnb style guide)
What is Browserify?
o Tool for compiling
node-flavored
commonjs modules
for the browser
o Allows you to nicely
organize your code
o Promotes code
modularity
What are commonjs
modules?
o Were created in the early
days of server side
JavaScript
o Three main variables:
o require
o exports
o module
CommonJs
var numberGreaterThanOrEqualTo = require('./numberGreaterThanOrEqualTo');
console.log(numberGreaterThanOrEqualTo(4,2));
Declaration of numberGreaterThanOrEqualTo.js
Usage of module
var numberGreaterThanOrEqualTo = function( value, testValue ){
if(isNaN(value)){
return false;
}
if(isNaN(testValue)){
return true;
}
return Number(value) >= Number(testValue);
};
module.exports = numberGreaterThanOrEqualTo;
Commonjs/Browserify module
Demo
Tools
Webstorm
Node for visual studio
What is React
 Just the UI
 Virtual DOM
 One way reactive data flow
Why React
o You can try it out
incrementally
o Facebook/Instagr
am actually use it
on their
important
products.
o All about
composition
Why React Contd.
o One way data-
binding
o Performance
o Not just the web
o Server sider
rendering
Why not the other
guys
o Angular
o Backbone
o Ember
o Durandal/Aurelia
o Knockout
Who is using it/migrating to
it?
o Khan Academy
o AirBnB
o Yahoo mail
o Flipboard canvas
o Github (issue
viewer)
o Atalassian HipChat
rewrite
What is the Virtual
DOM?
o Copy of the actual DOM
o When any change
happens re-render
everything to virtual
DOM
o Has its own diff algorithm
to learn what has
changed
o Only update real DOM
with changes only
JSX FTW!
var HelloMessage = React.createClass({
render: function() {
return (
<div
className='thisCanNotBeRight'>
Hello {this.props.name}
</div>);
}
});
React.render(<HelloMessage name="John" />,
mountNode);
Benefits of not
Data-Binding (JSX)
o JsHint,JSCS your
code
o Minification
o Type Checking
o Testable
Think in React
o Break up your User
Interface into
hierarchical pieces
o Create a static
version of your of
your interface
o Stake out a basic
representation of
your state
o Decide where your
state should live
State and Props
o Props are how
you pass data to
a child/owned
component
o State is the
internal state of
module
o Both trigger a re-
render
State
• this.setState({
mykey: 'my value'
});
o var value =
this.state.myKey;
o Should have one
source of truth
Component Specs
o ReactElement
render()
o object
getInitialState()
o object propTypes
o array mixins
o object statics
propTypes
propTypes: {
// You can declare that a prop is a specific JS primitive. By default, these
// are all optional.
optionalArray: React.PropTypes.array,
optionalString: React.PropTypes.string,
optionalUnion: React.PropTypes.oneOfType([
React.PropTypes.string,
React.PropTypes.number,
React.PropTypes.instanceOf(Message)
]),
// An array of a certain type
optionalArrayOf: React.PropTypes.arrayOf(React.PropTypes.number),
optionalObjectOf: React.PropTypes.objectOf(React.PropTypes.number),
optionalObjectWithShape: React.PropTyes.shape({
color: React.PropTypes.string,
fontSize: React.PropTypes.number
}),
requiredFunc: React.PropTypes.func.isRequired,
customProp: function(props, propName, componentName) {
if (!/matchme/.test(props[propName])) {
return new Error('Validation failed!');
}
}
* When an invalid value is
provided for a prop, a
warning will be shown in the
JavaScript console. Note
that for performance
reasons propTypes is only
checked in development
mode.
Component Specs
var React = require("React");
var Router = require('react-router');
var Sample = React.createClass({
mixins: [ Router.Navigation, Router.State ],
propTypes: {
optionalString: React.PropTypes.string
},
getInitialState: function() {
return {optionalString: this.props.optionalString};
},
render: function(){
return (
<div className="row">
{this.state.optionalString}
</div>
);
}
});
module.exports = Sample;
Lifecycle Methods
o componentWillMount
o componenetDidMount
o componentWillReceiveProps
o shouldComponentUpdate
o componentWillUpdate
o componentDidUpdate
o componentWillUnmount
Lifecycle Methods
componentWillMount
Invoked once, both on the client and server, immediately before the
initial rendering occurs.
invoked once, only on the client (not on the server), immediately after
the initial rendering occurs. At this point in the lifecycle, the
component has a DOM representation which you can access via
React.findDOMNode(this)
componentDidMount
Lifecycle Methods contd...
componentWillReceiveProps
TODO
TODO
shouldComponentUpdate
Lifecycle Methods contd...
componentWillUpdate
TODO
TODO
componentDidUpdate
Lifecycle Methods contd...
componentWillUnmount
TODO
React
Demo
What is Flux
 Also brought to you by Facebook
 Uni-directional data flow
 Works great with React
 More of a pattern, than a framework
 Pub/Sub pattern
How does it work
With more info
A Closer look…
Major parts of a Flux app
o Dispatcher
o Stores
o Views (React components)
Dispatcher
o Singleton that is the central
hub for an app
o When new data comes it
propagates to all stores
through callbacks
o Propagation triggered by
dispatch()
Dispatcher
var Dispatcher = require('flux').Dispatcher;
var assign = require('object-assign');
var PayloadSources = require('../constants/PayloadSources');
function throwExceptionIfActionNotSpecified(action) {
if (!action.type) {
throw new Error('Action type was not provided');
}
}
var AppDispatcher = assign(new Dispatcher(), {
handleServerAction: function(action) {
console.info('server action', action);
throwExceptionIfActionNotSpecified(action);
this.dispatch({
source: PayloadSources.SERVER_ACTION,
action: action
});
},
handleViewAction: function(action) {
console.info('view action', action);
throwExceptionIfActionNotSpecified(action);
this.dispatch({
source: PayloadSources.VIEW_ACTION,
action: action
});
}
});
module.exports = AppDispatcher;
ActionCreators
o a library of helper methods
o create the action object
and pass the action to the
dispatcher
o flow into the stores through
the callbacks they define
and register
ActionCreators
var AppDispatcher = require('../dispatcher/AppDispatcher');
var CharacterApiUtils = require('../utils/CharacterApiUtils');
var CharacterConstants = require('../constants/CharacterConstants');
var CharacterActions = {
receiveAll: function(characters) {
AppDispatcher.handleServerAction({
type: CharacterConstants.ActionTypes.RECEIVE_CHARACTERS,
characters: characters
});
},
loadAll: function() {
CharacterApiUtils.getCharacters(CharacterActions.receiveAll);
}
};
module.exports = CharacterActions;
CharacterConstants
var ApiConstants = require('./ApiConstants');
var keymirror = require('keymirror');
module.exports = {
ApiEndPoints: {
CHARACTER_GET: ApiConstants.API_ROOT + '/Character'
},
ActionTypes: keymirror({
RECEIVE_CHARACTERS: null
})
};
CharacterApiUtils
var $ = require('jquery');
var CharacterConstants = require('../constants/CharacterConstants');
var CharacterApiUtils = {
getCharacters: function(successCallback) {
$.get(CharacterConstants.ApiEndPoints.CHARACTER_GET)
.done(function(data) {
successCallback(data);
});
}
};
module.exports = CharacterApiUtils;
Stores
o Contain application state
and logic
o Singleton
o Similar to MVC, except they
manage state of more
than one object
o Registers itself with the
dispatcher through
callbacks
o When updated, they
broadcast a change event
for views that are listening
Stores var AppDispatcher = require('../dispatcher/AppDispatcher');
var EventEmitter = require('events').EventEmitter;
var CharacterConstants = require('../constants/CharacterConstants');
var assign = require('object-assign');
var CHANGE_EVENT = 'change';
var _characters = [];
var CharacterStore = assign({}, EventEmitter.prototype, {
init: function(characters) {
characters.forEach(function(character) {
_characters[character.id] = character;
}, this);
},
getAll: function() {
return _characters;
},
emitChange: function() {
this.emit(CHANGE_EVENT);
},
addChangeListener: function(callback) {
this.on(CHANGE_EVENT, callback);
},
removeChangeListener: function(callback) {
this.removeChangeListener(CHANGE_EVENT, callback);
}
});
AppDispatcher.register(function(payload) {
var action = payload.action;
switch (action.type) {
case CharacterConstants.ActionTypes.RECEIVE_CHARACTERS:
CharacterStore.init(action.characters);
CharacterStore.emitChange();
break;
}
});
module.exports = CharacterStore;
Flux
Demo
Implementation First Phase
1. Learn how to do this stuff on your own time
2. Start simple (JSHINT, JSCS)
3. Use Change management principles
 Up to you to explain what is in it for them
Change Management
Implement React and Flux
If using ASP.NET MVC try React.Net first
Use on the next feature you work on (may require you
spending your own private time)
Write a blog/wiki on the experience
Then let others have their input/concerns heard
Chrome Dev Tools
Postman
JSON pretty
React plugin
Thank you!
@JeffDutraCanada
Jeff.dutra@gmail.com
https://github.com/jefferydutra/

More Related Content

PPTX
Adding a modern twist to legacy web applications
PDF
Web ui tests examples with selenide, nselene, selene & capybara
PPTX
Owl: The New Odoo UI Framework
PDF
KISS Automation.py
PDF
Selenide alternative in Python - Introducing Selene [SeleniumCamp 2016]
PPTX
Developing New Widgets for your Views in Owl
PDF
What's Coming in Spring 3.0
PDF
Everything You (N)ever Wanted to Know about Testing View Controllers
Adding a modern twist to legacy web applications
Web ui tests examples with selenide, nselene, selene & capybara
Owl: The New Odoo UI Framework
KISS Automation.py
Selenide alternative in Python - Introducing Selene [SeleniumCamp 2016]
Developing New Widgets for your Views in Owl
What's Coming in Spring 3.0
Everything You (N)ever Wanted to Know about Testing View Controllers

What's hot (20)

PDF
Ember and containers
PDF
Advanced Dagger talk from 360andev
PDF
Redux vs Alt
PDF
You do not need automation engineer - Sqa Days - 2015 - EN
PDF
Quick: Better Tests via Incremental Setup
PDF
React lecture
PPTX
Good karma: UX Patterns and Unit Testing in Angular with Karma
PDF
Testing view controllers with Quick and Nimble
PPTX
Sword fighting with Dagger GDG-NYC Jan 2016
PPTX
Architecting Single Activity Applications (With or Without Fragments)
PPT
Ajax
PDF
SilverStripe CMS JavaScript Refactoring
ODP
Getting to Grips with SilverStripe Testing
PDF
Having Fun with Play
PDF
Practical Protocol-Oriented-Programming
PDF
QA Fest 2017. Яков Крамаренко. Minimum Usable Framework
PDF
Integrating React.js with PHP projects
PDF
Understanding JavaScript Testing
PPTX
Guide to Destroying Codebases The Demise of Clever Code
PDF
Adventures In JavaScript Testing
Ember and containers
Advanced Dagger talk from 360andev
Redux vs Alt
You do not need automation engineer - Sqa Days - 2015 - EN
Quick: Better Tests via Incremental Setup
React lecture
Good karma: UX Patterns and Unit Testing in Angular with Karma
Testing view controllers with Quick and Nimble
Sword fighting with Dagger GDG-NYC Jan 2016
Architecting Single Activity Applications (With or Without Fragments)
Ajax
SilverStripe CMS JavaScript Refactoring
Getting to Grips with SilverStripe Testing
Having Fun with Play
Practical Protocol-Oriented-Programming
QA Fest 2017. Яков Крамаренко. Minimum Usable Framework
Integrating React.js with PHP projects
Understanding JavaScript Testing
Guide to Destroying Codebases The Demise of Clever Code
Adventures In JavaScript Testing
Ad

Similar to Adding a modern twist to legacy web applications (20)

PDF
From Legacy to Hexagonal (An Unexpected Android Journey)
PDF
Intro to React - Featuring Modern JavaScript
PDF
Rails is not just Ruby
PDF
Json generation
PPTX
[Final] ReactJS presentation
KEY
Asynchronous Interfaces
PDF
React & The Art of Managing Complexity
KEY
Javascript unit testing, yes we can e big
PDF
OttawaJS - React
PDF
Professional JavaScript: AntiPatterns
PPTX
Intro react js
PDF
Javascript Frameworks for Joomla
PDF
React 101
PDF
N Things You Don't Want to Repeat in React Native
PDF
WebNet Conference 2012 - Designing complex applications using html5 and knock...
KEY
JavaScript Growing Up
PDF
ClojureScript - Making Front-End development Fun again - John Stevenson - Cod...
PPTX
Fullstack JS Workshop
PPTX
PDF
Materi Modern React Redux Power Point.pdf
From Legacy to Hexagonal (An Unexpected Android Journey)
Intro to React - Featuring Modern JavaScript
Rails is not just Ruby
Json generation
[Final] ReactJS presentation
Asynchronous Interfaces
React & The Art of Managing Complexity
Javascript unit testing, yes we can e big
OttawaJS - React
Professional JavaScript: AntiPatterns
Intro react js
Javascript Frameworks for Joomla
React 101
N Things You Don't Want to Repeat in React Native
WebNet Conference 2012 - Designing complex applications using html5 and knock...
JavaScript Growing Up
ClojureScript - Making Front-End development Fun again - John Stevenson - Cod...
Fullstack JS Workshop
Materi Modern React Redux Power Point.pdf
Ad

Recently uploaded (20)

PPTX
Lecture 3: Operating Systems Introduction to Computer Hardware Systems
PDF
Build Multi-agent using Agent Development Kit
PDF
Best Practices for Rolling Out Competency Management Software.pdf
PPTX
ISO 45001 Occupational Health and Safety Management System
PDF
top salesforce developer skills in 2025.pdf
PPTX
L1 - Introduction to python Backend.pptx
PPTX
Agentic AI : A Practical Guide. Undersating, Implementing and Scaling Autono...
PDF
Claude Code: Everyone is a 10x Developer - A Comprehensive AI-Powered CLI Tool
DOCX
The Five Best AI Cover Tools in 2025.docx
PPTX
What to Capture When It Breaks: 16 Artifacts That Reveal Root Causes
PDF
PTS Company Brochure 2025 (1).pdf.......
PDF
QAware_Mario-Leander_Reimer_Architecting and Building a K8s-based AI Platform...
PDF
How to Choose the Right IT Partner for Your Business in Malaysia
PPTX
Odoo POS Development Services by CandidRoot Solutions
PDF
Why TechBuilder is the Future of Pickup and Delivery App Development (1).pdf
PDF
IEEE-CS Tech Predictions, SWEBOK and Quantum Software: Towards Q-SWEBOK
PPT
Introduction Database Management System for Course Database
PDF
Upgrade and Innovation Strategies for SAP ERP Customers
PPTX
CHAPTER 12 - CYBER SECURITY AND FUTURE SKILLS (1) (1).pptx
PDF
2025 Textile ERP Trends: SAP, Odoo & Oracle
Lecture 3: Operating Systems Introduction to Computer Hardware Systems
Build Multi-agent using Agent Development Kit
Best Practices for Rolling Out Competency Management Software.pdf
ISO 45001 Occupational Health and Safety Management System
top salesforce developer skills in 2025.pdf
L1 - Introduction to python Backend.pptx
Agentic AI : A Practical Guide. Undersating, Implementing and Scaling Autono...
Claude Code: Everyone is a 10x Developer - A Comprehensive AI-Powered CLI Tool
The Five Best AI Cover Tools in 2025.docx
What to Capture When It Breaks: 16 Artifacts That Reveal Root Causes
PTS Company Brochure 2025 (1).pdf.......
QAware_Mario-Leander_Reimer_Architecting and Building a K8s-based AI Platform...
How to Choose the Right IT Partner for Your Business in Malaysia
Odoo POS Development Services by CandidRoot Solutions
Why TechBuilder is the Future of Pickup and Delivery App Development (1).pdf
IEEE-CS Tech Predictions, SWEBOK and Quantum Software: Towards Q-SWEBOK
Introduction Database Management System for Course Database
Upgrade and Innovation Strategies for SAP ERP Customers
CHAPTER 12 - CYBER SECURITY AND FUTURE SKILLS (1) (1).pptx
2025 Textile ERP Trends: SAP, Odoo & Oracle

Adding a modern twist to legacy web applications

  • 1. Adding a Modern Twist to Legacy Web Applications Process, Toolset and Buy In by Jeff Dutra - @JeffDutraCanada
  • 2. Housekeeping All the code will be on GitHub  https://github.com/jefferydutra/AddingModernTwistToLegacyApps
  • 3. Who Am I o It does not really matter o Not an Authority
  • 4. Who Am I o software developer/amateur skeptic/pretend psychologist o Proficient Web Developer working towards becoming an Expert
  • 5. Introduction  Manage dependencies and build your JavaScript with Node.js, Gulp, Browserify  Adding modern web functionality with React and Flux  Strategies for Buy In to start using these toolsets now (or in some reasonable amount of time)
  • 6. But Why?  Avoid misery of working with legacy code  We will see how you can add independent and isolated components to existing pages; pages that may be difficult to change  React and Flux allow you to make self-contained additions that handle their own data access/persistence
  • 8. What is Gulp • Grabs some files • Modify them • Output new files A build system should only handle basic functionality and allow other libraries to do things they are made to do.
  • 9. Why build with Gulp? o Minify o Concatenate o JSHint o Compile LESS or SASS o Run your tests (now there is no excuse when it comes to writing tests)
  • 10. Why not Grunt o Code over configuration o Grunt tries do everything itself o Gulp relies on an eco-system of plug-ins o Faster o Cooler logo
  • 11. The 4 functions Gulp provides o gulp.task(name[, deps], fn) o gulp.src(globs[, options]) o gulp.dest(path[, options]) o gulp.watch(glob[, opts], tasks) globs are a pattern or an array of patterns for file matching. **/*.js = find all files that end in .js
  • 12. JSHint Task var gulp = require('gulp'); var jshint = require('gulp-jshint'); var stylish = require('jshint-stylish'); var notify = require("gulp-notify"); gulp.task('jshint', function () { return gulp.src("./js/library/src/**/*.js") .pipe(jshint('.jshintrc')) .pipe(jshint.reporter(stylish)) .pipe(notify(function (file) { if (file.jshint.success) { // Don't show something if success return false; } var errors = file.jshint.results.map(function (data) { if (data.error) { return "(" + data.error.line + ':' + data.error.character + ') ' + data.error.reason; } }).join("n"); return file.relative + " (" + file.jshint.results.length + " errors)n" + errors; }));
  • 14. JsHint Task Demo (using AirBnb style guide)
  • 15. What is Browserify? o Tool for compiling node-flavored commonjs modules for the browser o Allows you to nicely organize your code o Promotes code modularity
  • 16. What are commonjs modules? o Were created in the early days of server side JavaScript o Three main variables: o require o exports o module
  • 17. CommonJs var numberGreaterThanOrEqualTo = require('./numberGreaterThanOrEqualTo'); console.log(numberGreaterThanOrEqualTo(4,2)); Declaration of numberGreaterThanOrEqualTo.js Usage of module var numberGreaterThanOrEqualTo = function( value, testValue ){ if(isNaN(value)){ return false; } if(isNaN(testValue)){ return true; } return Number(value) >= Number(testValue); }; module.exports = numberGreaterThanOrEqualTo;
  • 20. What is React  Just the UI  Virtual DOM  One way reactive data flow
  • 21. Why React o You can try it out incrementally o Facebook/Instagr am actually use it on their important products. o All about composition
  • 22. Why React Contd. o One way data- binding o Performance o Not just the web o Server sider rendering
  • 23. Why not the other guys o Angular o Backbone o Ember o Durandal/Aurelia o Knockout
  • 24. Who is using it/migrating to it? o Khan Academy o AirBnB o Yahoo mail o Flipboard canvas o Github (issue viewer) o Atalassian HipChat rewrite
  • 25. What is the Virtual DOM? o Copy of the actual DOM o When any change happens re-render everything to virtual DOM o Has its own diff algorithm to learn what has changed o Only update real DOM with changes only
  • 26. JSX FTW! var HelloMessage = React.createClass({ render: function() { return ( <div className='thisCanNotBeRight'> Hello {this.props.name} </div>); } }); React.render(<HelloMessage name="John" />, mountNode);
  • 27. Benefits of not Data-Binding (JSX) o JsHint,JSCS your code o Minification o Type Checking o Testable
  • 28. Think in React o Break up your User Interface into hierarchical pieces o Create a static version of your of your interface o Stake out a basic representation of your state o Decide where your state should live
  • 29. State and Props o Props are how you pass data to a child/owned component o State is the internal state of module o Both trigger a re- render
  • 30. State • this.setState({ mykey: 'my value' }); o var value = this.state.myKey; o Should have one source of truth
  • 31. Component Specs o ReactElement render() o object getInitialState() o object propTypes o array mixins o object statics
  • 32. propTypes propTypes: { // You can declare that a prop is a specific JS primitive. By default, these // are all optional. optionalArray: React.PropTypes.array, optionalString: React.PropTypes.string, optionalUnion: React.PropTypes.oneOfType([ React.PropTypes.string, React.PropTypes.number, React.PropTypes.instanceOf(Message) ]), // An array of a certain type optionalArrayOf: React.PropTypes.arrayOf(React.PropTypes.number), optionalObjectOf: React.PropTypes.objectOf(React.PropTypes.number), optionalObjectWithShape: React.PropTyes.shape({ color: React.PropTypes.string, fontSize: React.PropTypes.number }), requiredFunc: React.PropTypes.func.isRequired, customProp: function(props, propName, componentName) { if (!/matchme/.test(props[propName])) { return new Error('Validation failed!'); } } * When an invalid value is provided for a prop, a warning will be shown in the JavaScript console. Note that for performance reasons propTypes is only checked in development mode.
  • 33. Component Specs var React = require("React"); var Router = require('react-router'); var Sample = React.createClass({ mixins: [ Router.Navigation, Router.State ], propTypes: { optionalString: React.PropTypes.string }, getInitialState: function() { return {optionalString: this.props.optionalString}; }, render: function(){ return ( <div className="row"> {this.state.optionalString} </div> ); } }); module.exports = Sample;
  • 34. Lifecycle Methods o componentWillMount o componenetDidMount o componentWillReceiveProps o shouldComponentUpdate o componentWillUpdate o componentDidUpdate o componentWillUnmount
  • 35. Lifecycle Methods componentWillMount Invoked once, both on the client and server, immediately before the initial rendering occurs. invoked once, only on the client (not on the server), immediately after the initial rendering occurs. At this point in the lifecycle, the component has a DOM representation which you can access via React.findDOMNode(this) componentDidMount
  • 40. What is Flux  Also brought to you by Facebook  Uni-directional data flow  Works great with React  More of a pattern, than a framework  Pub/Sub pattern
  • 41. How does it work
  • 44. Major parts of a Flux app o Dispatcher o Stores o Views (React components)
  • 45. Dispatcher o Singleton that is the central hub for an app o When new data comes it propagates to all stores through callbacks o Propagation triggered by dispatch()
  • 46. Dispatcher var Dispatcher = require('flux').Dispatcher; var assign = require('object-assign'); var PayloadSources = require('../constants/PayloadSources'); function throwExceptionIfActionNotSpecified(action) { if (!action.type) { throw new Error('Action type was not provided'); } } var AppDispatcher = assign(new Dispatcher(), { handleServerAction: function(action) { console.info('server action', action); throwExceptionIfActionNotSpecified(action); this.dispatch({ source: PayloadSources.SERVER_ACTION, action: action }); }, handleViewAction: function(action) { console.info('view action', action); throwExceptionIfActionNotSpecified(action); this.dispatch({ source: PayloadSources.VIEW_ACTION, action: action }); } }); module.exports = AppDispatcher;
  • 47. ActionCreators o a library of helper methods o create the action object and pass the action to the dispatcher o flow into the stores through the callbacks they define and register
  • 48. ActionCreators var AppDispatcher = require('../dispatcher/AppDispatcher'); var CharacterApiUtils = require('../utils/CharacterApiUtils'); var CharacterConstants = require('../constants/CharacterConstants'); var CharacterActions = { receiveAll: function(characters) { AppDispatcher.handleServerAction({ type: CharacterConstants.ActionTypes.RECEIVE_CHARACTERS, characters: characters }); }, loadAll: function() { CharacterApiUtils.getCharacters(CharacterActions.receiveAll); } }; module.exports = CharacterActions;
  • 49. CharacterConstants var ApiConstants = require('./ApiConstants'); var keymirror = require('keymirror'); module.exports = { ApiEndPoints: { CHARACTER_GET: ApiConstants.API_ROOT + '/Character' }, ActionTypes: keymirror({ RECEIVE_CHARACTERS: null }) }; CharacterApiUtils var $ = require('jquery'); var CharacterConstants = require('../constants/CharacterConstants'); var CharacterApiUtils = { getCharacters: function(successCallback) { $.get(CharacterConstants.ApiEndPoints.CHARACTER_GET) .done(function(data) { successCallback(data); }); } }; module.exports = CharacterApiUtils;
  • 50. Stores o Contain application state and logic o Singleton o Similar to MVC, except they manage state of more than one object o Registers itself with the dispatcher through callbacks o When updated, they broadcast a change event for views that are listening
  • 51. Stores var AppDispatcher = require('../dispatcher/AppDispatcher'); var EventEmitter = require('events').EventEmitter; var CharacterConstants = require('../constants/CharacterConstants'); var assign = require('object-assign'); var CHANGE_EVENT = 'change'; var _characters = []; var CharacterStore = assign({}, EventEmitter.prototype, { init: function(characters) { characters.forEach(function(character) { _characters[character.id] = character; }, this); }, getAll: function() { return _characters; }, emitChange: function() { this.emit(CHANGE_EVENT); }, addChangeListener: function(callback) { this.on(CHANGE_EVENT, callback); }, removeChangeListener: function(callback) { this.removeChangeListener(CHANGE_EVENT, callback); } }); AppDispatcher.register(function(payload) { var action = payload.action; switch (action.type) { case CharacterConstants.ActionTypes.RECEIVE_CHARACTERS: CharacterStore.init(action.characters); CharacterStore.emitChange(); break; } }); module.exports = CharacterStore;
  • 53. Implementation First Phase 1. Learn how to do this stuff on your own time 2. Start simple (JSHINT, JSCS) 3. Use Change management principles  Up to you to explain what is in it for them
  • 55. Implement React and Flux If using ASP.NET MVC try React.Net first Use on the next feature you work on (may require you spending your own private time) Write a blog/wiki on the experience Then let others have their input/concerns heard
  • 56. Chrome Dev Tools Postman JSON pretty React plugin