$30 off During Our Annual Pro Sale. View Details »

React - A JavaScript library for building user interfaces

Helielson
October 04, 2014

React - A JavaScript library for building user interfaces

Talk about ReactJS presented at JusBrasil

Helielson

October 04, 2014
Tweet

More Decks by Helielson

Other Decks in Programming

Transcript

  1. A javascript library for building user interfaces

    View Slide

  2. Helielson
    @hyetho
    @helielson

    View Slide

  3. Topics
    What is React?
    Components
    SEO
    Performance
    Testing
    Community
    Who uses

    View Slide

  4. What's the best way to structure
    javascript applications?

    View Slide

  5. There are a lot of javascript frameworks

    View Slide

  6. Agility.js
    AngularJS
    Backbone.js
    CanJS
    Derby
    Dojo
    Ember.js
    Firebase + AngularJS
    Flight
    jQuery
    KnockoutJS
    Knockback.js
    Maria
    Meteor
    Polymer
    React
    SocketStream
    Vanilla JS
    YUI
    todomvc.com

    View Slide

  7. Most of them...
    Observable Objects
    Mutation -> Update

    View Slide

  8. What do we need?
    Re-render the entire component

    View Slide

  9. How?

    View Slide

  10. Re-rendering the DOM on each update is
    very expensive

    View Slide

  11. On each update
    - builds a new virtual DOM subtree
    - diffs it with the old one
    - computes the minimal set of DOM mutations
    and put them in a queue
    - batch executes all updates

    View Slide

  12. View Slide

  13. But, what's react?

    View Slide

  14. View Slide

  15. Is it a template language like handlebars.js?

    View Slide

  16. Nooooooooooo!
    "To set the record straight: React components are
    far more powerful than Angular templates; they
    should be compared with Angular’s directives
    instead. [Directives are Angular's way of creating
    custom elements]."
    Pete Hunt
    quora.com/Pete-Hunt/Posts/Facebooks-React-vs-AngularJS-A-Closer-Look

    View Slide

  17. var React = require('React');
    var HelloMessage = React.createClass({
    render: function() {
    return React.DOM.div(
    null, "Hello ", this.props.name);
    }
    });
    React.renderComponent(
    HelloMessage({name: "John"}),
    mountNode);
    my-button.js

    View Slide

  18. var React = require('React');
    var HelloMessage = React.createClass({
    render: function() {
    return React.DOM.div(
    null, "Hello ", this.props.name);
    }
    });
    React.renderComponent(
    HelloMessage({name: "John"}),
    mountNode);
    my-button.js

    View Slide

  19. var React = require('React');
    var HelloMessage = React.createClass({
    render: function() {
    return React.DOM.div(
    null, "Hello ", this.props.name);
    }
    });
    React.renderComponent(
    HelloMessage({name: "John"}),
    mountNode);
    my-button.js

    View Slide

  20. var React = require('React');
    var HelloMessage = React.createClass({
    render: function() {
    return React.DOM.div(
    null, "Hello ", this.props.name);
    }
    });
    React.renderComponent(
    HelloMessage({name: "John"}),
    mountNode);
    my-button.js

    View Slide

  21. var React = require('React');
    var HelloMessage = React.createClass({
    render: function() {
    return React.DOM.div(
    null, "Hello ", this.props.name);
    }
    });
    React.renderComponent(
    HelloMessage({name: "John"}),
    mountNode);
    my-button.js

    View Slide

  22. var React = require('React');
    var HelloMessage = React.createClass({
    render: function() {
    return (
    Hello {this.props.name}
    );
    }
    });
    React.renderComponent(
    HelloMessage({name: "John"}), mountNode);
    my-button.jsx

    View Slide

  23. Components
    "A highly cohesive building block for UIs loosely
    coupled with other components"
    Pete Hunt

    View Slide

  24. Components
    "Reusable API that encapsulate a bunch of
    different stuff"
    Tom Occhino

    View Slide

  25. - It's the markup
    - It's the javascript
    - It's the behavior's function
    It's more than a template

    View Slide

  26. The render function
    render: function() {
    }

    View Slide


  27. var MyButton = React.createClass({
    render: function() {
    return (
    className="my-button"
    onClick={this.props.onAction}>
    {this.props.text}

    );
    }
    });

    View Slide


  28. var MyButton = React.createClass({
    render: function() {
    return (
    className="my-button"
    onClick={this.props.onAction}>
    {this.props.text}

    );
    }
    });

    View Slide

  29. The state

    View Slide

  30. var Timer = React.createClass({
    });

    View Slide

  31. var Timer = React.createClass({
    getInitialState: function() {
    return {secondsElapsed: 0};
    },
    render: function() {
    }
    });

    View Slide

  32. var Timer = React.createClass({
    getInitialState: function() {
    return {secondsElapsed: 0};
    },
    render: function() {
    this.state.secondsElapsed; // 0
    }
    });

    View Slide

  33. var Timer = React.createClass({
    tick: function() {
    var current = this.state.secoundsElapsed;
    this.setState({
    secondsElapsed: current + 1
    });
    }
    });

    View Slide

  34. var Timer = React.createClass({
    componentDidMount: function() {
    this.interval = setInterval(
    this.tick, 1000);
    },
    componentWillUnmount: function() {
    clearInterval(this.interval);
    }
    });

    View Slide

  35. var Timer = React.createClass({
    getInitialState: function() {},
    tick: function() {},
    componentDidMount: function() {},
    componentWillUnmount: function() {},
    render: function() {}
    });

    View Slide

  36. Lifecycle functions
    componentDidMount: function() {},
    componentWillmount: function() {},
    componentWillUnmount: function() {},
    componentWillReceiveProps: function() {},
    componentComponentUpdate: function() {},
    componentWillUpdate: function() {},
    componentDidUpdate: function() {},

    View Slide

  37. Composable Components
    Inheritance

    View Slide

  38. var SetIntervalMixin = {
    componentWillMount: function() {
    this.intervals = [];
    },
    setInterval: function() {
    this.intervals.push(
    setInterval.apply(null, arguments));
    },
    componentWillUnmount: function() {
    this.intervals.map(clearInterval);
    }
    };

    View Slide

  39. var Timer = React.createClass({
    mixins: [setIntervalMixin],
    ...
    });

    View Slide

  40. SEO

    View Slide

  41. string renderComponentToString(
    ReactComponent component);

    View Slide

  42. And the best part of it is

    View Slide

  43. var html = React.renderComponentToString(
    HelloMessage({name: "John"}));
    Server
    Client


    {{html}}


    React.renderComponent(
    HelloMessage({name: "John"}), mountNode);

    View Slide

  44. var html = React.renderComponentToString(
    HelloMessage({name: "John"}));
    Server
    Client


    {{html}}


    React.renderComponent(
    HelloMessage({name: "John"}), mountNode);

    View Slide

  45. var html = React.renderComponentToString(
    HelloMessage({name: "John"}));
    Server
    Client


    {{html}}


    React.renderComponent(
    HelloMessage({name: "John"}), mountNode);

    View Slide

  46. Is the data updated?
    Only attaches the event handlers

    View Slide

  47. Performance

    View Slide

  48. Show lists of 1500 rows
    Angular: 1.35s
    ReactJs: 310ms
    www.williambrownstreet.net/blog/2014/04/faster-angularjs-rendering-angularjs-and-reactjs

    View Slide

  49. Testing

    View Slide

  50. View Slide

  51. var CheckboxWithLabel = React.createClass({
    getInitialState: function() {
    return { isChecked: false };
    },
    onChange: function() {
    this.setState({isChecked: !this.state.isChecked});
    },
    render: function() {
    return (

    checked={this.state.isChecked}
    onChange={this.onChange}/>
    {this.state.isChecked ? this.props.labelOn :
    this.props.labelOff}
    );
    }
    });
    module.exports = CheckboxWithLabel;

    View Slide

  52. var CheckboxWithLabel = React.createClass({
    getInitialState: function() {
    return { isChecked: false };
    },
    onChange: function() {
    this.setState({isChecked: !this.state.isChecked});
    },
    render: function() {
    return (

    checked={this.state.isChecked}
    onChange={this.onChange}/>
    {this.state.isChecked ? this.props.labelOn :
    this.props.labelOff}
    );
    }
    });
    module.exports = CheckboxWithLabel;

    View Slide

  53. jest.dontMock('../CheckboxWithLabel.js');
    describe('CheckboxWithLabel', function() {
    it('changes the text after click', function() {
    var React = require('react/addons');
    var CheckboxWithLabel = require('..
    /CheckboxWithLabel.js');
    var TestUtils = React.addons.TestUtils;
    var checkbox = TestUtils.renderIntoDocument(

    );
    });
    });

    View Slide

  54. jest.dontMock('../CheckboxWithLabel.js');
    describe('CheckboxWithLabel', function() {
    it('changes the text after click', function() {
    var React = require('react/addons');
    var CheckboxWithLabel = require('..
    /CheckboxWithLabel.js');
    var TestUtils = React.addons.TestUtils;
    var checkbox = TestUtils.renderIntoDocument(

    );
    });
    });

    View Slide

  55. jest.dontMock('../CheckboxWithLabel.js');
    describe('CheckboxWithLabel', function() {
    it('changes the text after click', function() {
    var React = require('react/addons');
    var CheckboxWithLabel = require('..
    /CheckboxWithLabel.js');
    var TestUtils = React.addons.TestUtils;
    var checkbox = TestUtils.renderIntoDocument(

    );
    });
    });

    View Slide

  56. jest.dontMock('../CheckboxWithLabel.js');
    describe('CheckboxWithLabel', function() {
    it('changes the text after click', function() {
    var React = require('react/addons');
    var CheckboxWithLabel = require('..
    /CheckboxWithLabel.js');
    var TestUtils = React.addons.TestUtils;
    var checkbox = TestUtils.renderIntoDocument(

    );
    });
    });

    View Slide

  57. jest.dontMock('../CheckboxWithLabel.js');
    describe('CheckboxWithLabel', function() {
    it('changes the text after click', function() {
    var React = require('react/addons');
    var CheckboxWithLabel = require('..
    /CheckboxWithLabel.js');
    var TestUtils = React.addons.TestUtils;
    var checkbox = TestUtils.renderIntoDocument(

    );
    });
    });

    View Slide

  58. // Verify that it's Off by default
    var label = TestUtils.findRenderedDOMComponentWithTag(
    checkbox, 'label');
    expect(
    label.getDOMNode().textContent).toEqual('Off');
    // Simulate a click and verify that it is now On
    var input = TestUtils.findRenderedDOMComponentWithTag(
    checkbox, 'input');
    TestUtils.Simulate.change(input);
    expect(
    label.getDOMNode().textContent).toEqual('On');

    View Slide

  59. // Verify that it's Off by default
    var label = TestUtils.findRenderedDOMComponentWithTag(
    checkbox, 'label');
    expect(
    label.getDOMNode().textContent).toEqual('Off');
    // Simulate a click and verify that it is now On
    var input = TestUtils.findRenderedDOMComponentWithTag(
    checkbox, 'input');
    TestUtils.Simulate.change(input);
    expect(
    label.getDOMNode().textContent).toEqual('On');

    View Slide

  60. Community

    View Slide

  61. View Slide

  62. Who uses?

    View Slide

  63. umrum.io

    View Slide

  64. How it's being used at umrum.io

    View Slide

  65. View Slide

  66. How it's being used at JusBrasil Newsletter

    View Slide

  67. View Slide

  68. @hyetho
    @helielson
    Questions?

    View Slide

  69. References
    facebook.github.io/react/docs/
    www.funnyant.com/reactjs-what-is-it/
    youtube.com/watch?v=XxVg_s8xAms
    youtube.com/watch?v=x7cQ3mrcKaY

    View Slide

  70. Tools
    markup.su/highlighter
    drive.google.com
    pixlr.com/editor

    View Slide