Upgrade to Pro — share decks privately, control downloads, hide ads and more …

React Amsterdam: Migrating safely to React

Jamis Charles
April 16, 2016
960

React Amsterdam: Migrating safely to React

Part 2 of my "migrating to React" talk

Jamis Charles

April 16, 2016
Tweet

Transcript

  1. • too many abstraction layers • low confidence • difficult

    state bugs (currency codes mismatched etc) Pain
  2. • V1: Just ship it • Maintainability is low priority

    • Complexity rises What happened?
  3. • React simplifies the view (fewer files) • Quick win

    • Push it to prod • Learn & evaluate Lessons learned
  4. • Backbone Router + custom routing logic • complex •

    difficult to track url -> code • good opportunity Routing Layer
  5. require('backboneSubroute'); module.exports = Backbone.SubRoute.extend({ showView: function (options) { if (options.name)

    { this.loadScripts(options); } historyModel.addPath(options.name); }, getPath: function (scriptName) { // getPath code }, loadScripts: function (options) { // loadScripts code }, cleanView: function () { // cleanView code } });
  6. // React Components... import MainContainer from '../containers/main'; import RequestContainer from

    '../containers/request'; import SendContainer from '../containers/send'; import BuyContainer from '../containers/buy'; ReactDOM.render( <Router history={history}> <Route path='/myaccount/transfer/' component={MainContainer}> {/* Flow entry points */} <Route path={'request(/:action)'} component={RequestContainer} /> <Route path={'send(/:action)'} component={SendContainer} /> <Route path={'buy(/:action)'} component={BuyContainer} /> </Route> </Router>, document.getElementById('react-transfer-container'));
  7. import React from 'react'; import indexView from '../index'; let SendContainer

    = React.createClass({ propTypes: { params: React.PropTypes.object.isRequired }, componentDidMount() { this.showBBView(); }, componentDidUpdate() { this.showBBView(); }, // will load and show a Backbone view. showBBView() { let type = 'send'; let action = this.props.params.action || 'recipient'; // gets content and renders it into the DOM. indexView.navigate(type, action); }, render() { return null; } }); export default SendContainer;
  8. import React from 'react'; import indexView from '../index'; let SendContainer

    = React.createClass({ propTypes: { params: React.PropTypes.object.isRequired }, componentDidMount() { this.showBBView(); }, componentDidUpdate() { this.showBBView(); }, // will load and show a Backbone view. showBBView() { let type = 'send'; let action = this.props.params.action || 'recipient'; // gets content and renders it into the DOM. indexView.navigate(type, action); }, render() { return null; } }); export default SendContainer;
  9. import React from 'react'; import indexView from '../index'; let SendContainer

    = React.createClass({ propTypes: { params: React.PropTypes.object.isRequired }, componentDidMount() { this.showBBView(); }, componentDidUpdate() { this.showBBView(); }, // will load and show a Backbone view. showBBView() { let type = 'send'; let action = this.props.params.action || 'recipient'; // gets content and renders it into the DOM. indexView.navigate(type, action); }, render() { return null; } }); export default SendContainer;
  10. import React from 'react'; import indexView from '../index'; let SendContainer

    = React.createClass({ propTypes: { params: React.PropTypes.object.isRequired }, componentDidMount() { this.showBBView(); }, componentDidUpdate() { this.showBBView(); }, // will load and show a Backbone view. showBBView() { let type = 'send'; let action = this.props.params.action || 'recipient'; // gets content and renders it into the DOM. indexView.navigate(type, action); }, render() { return null; } }); export default SendContainer;
  11. import React from 'react'; import * as routeUtil from '../utils/routeHelper';

    let SendContainer = React.createClass({ propTypes: { params: React.PropTypes.object.isRequired }, componentDidMount () { this.showBBView(); }, componentDidUpdate() { this.showBBView(); }, // will load and show a Backbone view. showBBView() { let type = 'send'; let action = this.props.params.action || 'recipient'; // gets content and renders it into the DOM. routeUtil.getIndexView().navigate(type, action); }, render() { return null; } }); export default SendContainer;
  12. import React from 'react'; import * as routeUtil from '../utils/routeHelper';

    let SendContainer = React.createClass({ propTypes: { params: React.PropTypes.object.isRequired }, render() { return <SendComponent /> } }); export default SendContainer;
  13. • Url → code is easy now • Reduced complexity

    • Good migration path for a give url Routing Layer
  14. • Backbone Models & Collections • complex • Most of

    our state pain comes from here Data Layer
  15. import $ from ‘jquery'; import Backbone from ‘backbone'; export default

    Backbone.View.extend({ el: 'form', events: { 'keyup #note': 'resizeTextAreaField', 'blur #note': 'hideTextAreaCounters' }, // Resize text area as user types resizeTextAreaField: function (event) { var count = this.countTextContent(); var newHeight = this.getIdealTextAreaHeight(count); var newRows = this.getRowsFromHeight(newHeight); $('#note').height(newHeight).attr('rows', newRows); }, // Update textarea counter with remaining character left hideTextAreaCounters: function (event) { // pseudo code },
  16. import $ from ‘jquery'; import Backbone from ‘backbone'; export default

    Backbone.View.extend({ el: 'form', events: { 'keyup #note': 'resizeTextAreaField', 'blur #note': 'hideTextAreaCounters' }, // Resize text area as user types resizeTextAreaField: function (event) { var count = this.countTextContent(); var newHeight = this.getIdealTextAreaHeight(count); var newRows = this.getRowsFromHeight(newHeight); $('#note').height(newHeight).attr('rows', newRows); }, // Update textarea counter with remaining character left hideTextAreaCounters: function (event) { // pseudo code },
  17. import $ from ‘jquery'; import Backbone from ‘backbone'; import *

    as ResizeUtil from 'utils/resizeTextareaUtil'; export default Backbone.View.extend({ el: 'form', events: { 'keyup #note': 'resizeTextAreaField', 'blur #note': 'hideTextAreaCounters' }, // Resize text area as user types resizeTextAreaField: ResizeUtil.resizeField, // Update textarea counter with remaining character left hideTextAreaCounters: ResizeUtil.hideTextArea });
  18. Sources • React Rally talk: https://www.youtube.com/ watch?v=mrtwImsEq5s • Moving from

    Require to Webpack 
 https://www.paypal-engineering.com/ 2015/08/07/1450/ • http://www.infoq.com/presentations/Simple- Made-Easy