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

ReactJS: Keep Simple. Everything can be a component!

Pedro Nauck
November 22, 2014

ReactJS: Keep Simple. Everything can be a component!

Talk about ReactJS and how to turn your development process to much easier and simple.

Pedro Nauck

November 22, 2014
Tweet

More Decks by Pedro Nauck

Other Decks in Programming

Transcript

  1. Component
    KEEP
    SIMPLE
    everything can be a
    it

    View Slide

  2. Pedro Nauck
    FRONTEND DEVELOPER
    @pedronauck
    pedronauck.com

    View Slide

  3. USER
    Interfaces

    View Slide

  4. The user interface is one
    of the most important
    parts of any program
    because it determines
    how easily you can
    make the program do
    what you want.

    View Slide

  5. But, what
    WEOUR
    customers
    want?

    View Slide

  6. find
    Value

    View Slide

  7. we need
    to deliver
    that
    Value

    View Slide

  8. it's
    just
    about
    Design
    not

    View Slide

  9. it's
    about design
    user experience
    quickly adapt
    performance
    scalability
    optimization

    View Slide

  10. design
    user experience
    quickly adapt
    performance
    scalability
    otimization
    }Simplicity

    View Slide

  11. complexity
    project size

    View Slide

  12. Because something is
    simple to you, doesn't
    mean it's for everyone

    View Slide

  13. when
    become
    complex
    ?
    a project

    View Slide

  14. questions answers

    View Slide

  15. Is  this  a  module  or  not?

    View Slide

  16. Do  I  need  a  directive  here?

    View Slide

  17. Should  I  create  a  
    factory  or  a  service?

    View Slide

  18. Why  this  shit  doesn’t  work?

    View Slide

  19. View Slide

  20. complexity
    value

    View Slide

  21. React
    how
    can help us
    with that?

    View Slide

  22. Javascript Library
    for building
    UI

    View Slide


  23. library
    framework

    View Slide

  24. library framework
    A tool to resolve just
    one specific thing
    A set of tools to
    resolve a lot of things

    View Slide

  25. library
    framework

    View Slide

  26. is using?
    who

    View Slide

  27. the real
    proposal
    around

    View Slide

  28. PROCESS
    simple!
    DEVELOPMENT
    is making your

    View Slide

  29. how?

    View Slide

  30. 1
    #

    View Slide

  31. without
    mutation

    View Slide

  32. without
    mutation
    We need a lightweight DOM
    We need control over our data
    We need to know what’s happening

    View Slide

  33. WE Don't
    NEED

    View Slide

  34. View Slide

  35. 2
    #

    View Slide

  36. forget views
    models
    controllers
    modules
    2-way binding
    observers
    templates
    {

    View Slide

  37. FOCUS ON
    Components
    your

    View Slide

  38. Component
    React is all about building reusable components.
    In fact, with React the only thing you do is build
    components. Since they're so encapsulated,
    components make code reuse, testing, and
    separation of concerns easy.
    http:/
    /bit.ly/why-react

    View Slide

  39. View Slide


  40. View Slide


  41. View Slide





  42. View Slide

  43. this is
    the concept
    just

    View Slide

  44. SHOW ME
    some code
    please!

    View Slide

  45. NewsItem.jsx
    var NewsItem = React.createClass({
    });
    render: function() {
    }
    var React = require('react');
    return (

    ...
    ...
    ...
    ...

    );

    View Slide

  46. NewsItem.jsx
    var NewsItem = React.createClass({
    });
    render: function() {
    }
    var React = require('react');
    return (

    ...
    ...
    ...
    ...

    );

    View Slide

  47. NewsItem.jsx
    var NewsItem = React.createClass({
    });
    render: function() {
    }
    var React = require('react');
    return (

    ...
    ...
    ...
    ...

    );
    factory
    pattern

    View Slide

  48. NewsItem.jsx
    var NewsItem = React.createClass({
    });
    render: function() {
    }
    var React = require('react');
    return (

    ...
    ...
    ...
    ...

    );

    View Slide

  49. NewsItem.jsx
    var NewsItem = React.createClass({
    });
    render: function() {
    }
    var React = require('react');
    return (

    ...
    ...
    ...
    ...

    );

    View Slide

  50. NewsItem.jsx
    var NewsItem = React.createClass({
    });
    render: function() {
    }
    var React = require('react');
    return (

    ...
    ...
    ...
    ...

    );

    View Slide

  51. View Slide

  52. JSX
    A Javascript XML based
    extension that compile just the
    template part of your code

    View Slide

  53. We strongly believe that
    components are the right way to
    separate concerns rather than
    "templates" and "display logic.”
    We think that markup and the
    code that generates it are
    intimately tied together.

    View Slide

  54. It makes a lot of sense that a
    JavaScript's template stays
    in the JavaScript

    @jcemer

    View Slide

  55. What's the
    difference?
    1
    #
    the concerns are mixing too


    <%= @post.author.name %>


    <%= @post.title %>


    <%= image_tag @post.image %>


    View Slide

  56. to much better
    than
    var title = 'Some title';
    var author = 'Jim Keneddy';
    var newsItem = '' +
    '' + author + '' +
    '' + title + '' +
    '' + '...' + '' +
    ' + '...' + ' +
    '';
    2
    #

    View Slide

  57. var NewsItem = React.createClass({
    });
    render: function() {
    }
    var React = require('react');
    return (

    ...
    ...
    ...
    ...

    );
    Will BE
    Compiled
    3
    #
    NewsItem.jsx

    View Slide

  58. NewsItem.js
    var React = require('react');
    var NewsItem = React.createClass({
    render: function() {
    }
    });
    return (
    React.createElement('article', {className: 'news-item'},
    React.createElement('div', {className: 'news-author'}, '...'),
    React.createElement('header', {className: 'news-title'}, '...'),
    React.createElement('figure', {className: 'news-cover'},
    '...',
    React.createElement('ul', {className: 'news-stats'}, '...')
    )
    )
    );

    View Slide

  59. But
    Why?

    View Slide

  60. because
    is
    mutation
    EVIL

    View Slide

  61. Virtual
    DOM

    View Slide

  62. An object tree that is a
    representation of the DOM.
    Kinda a "mirror".
    Virtual DOM

    View Slide

  63. Travolta
    DOM

    View Slide

  64. VirtualDOM
    ParentComponent
    ChildComponent
    ChildComponent
    ChildComponent ChildComponent
    ChildComponent

    View Slide

  65. EACH
    UPDATE
    VirtualDOM
    buid a new
    Virtual
    DOM tree
    diff algorithm
    with old
    compute minimal
    sets of mutation
    and put in a queue
    batch executes
    all updates

    View Slide

  66. Old Tree Mutations New Tree
    VirtualDOM

    View Slide

  67. EACH
    UPDATE
    VirtualDOM
    buid a new
    Virtual
    DOM tree
    diff algorithm
    with old
    compute minimal
    sets of mutation
    and put in a queue
    batch executes
    all updates
    Re-render
    the entire
    DOM

    View Slide

  68. Advantages:
    Javascript is Fast
    and the DOM
    is slow

    View Slide

  69. React
    Angular
    Time
    Time
    0ms 0.35ms 0.7ms 1.05ms 1.4ms
    1.35ms
    0.31ms
    Render a list with 1500 rows
    Benchmark

    View Slide

  70. View Slide

  71. return (

    ...
    ...

    ...
    ...


    );
    NewsItem.jsx
    kinda
    messy!
    render: function() {
    }

    View Slide

  72. WE NEED
    break
    to

    View Slide

  73. State
    &
    Props

    View Slide

  74. State
    &
    Props
    Where you manage the data
    of your components

    View Slide

  75. Props State
    Data that can be
    imutable
    Data that can be
    mutable

    View Slide

  76. Uniderectional
    DataFlow

    View Slide

  77. Components can either get
    imutable data (via props)
    or management their own
    state (via state)

    View Slide

  78. var React = require('react');
    var NewsItem = require('./components/NewsItem');
    var NewsFeed = React.createClass({
    render: function() {
    var posts = this.props.posts.map(function(post) {
    return
    });
    return {posts}
    }
    });
    NewsFeed.jsx

    View Slide

  79. var React = require('react');
    var NewsItem = require('./components/NewsItem');
    var NewsFeed = React.createClass({
    render: function() {
    var posts = this.props.posts.map(function(post) {
    return
    });
    return {posts}
    }
    });
    NewsFeed.jsx
    var posts = this.props.posts.map(function(post) {
    return
    });
    return {posts}
    var NewsItem = require('./components/NewsItem');

    View Slide

  80. var React = require('react');
    var NewsItem = require('./components/NewsItem');
    var NewsFeed = React.createClass({
    render: function() {
    var posts = this.props.posts.map(function(post) {
    return
    });
    return {posts}
    }
    });
    NewsFeed.jsx
    post={post}

    View Slide

  81. var NewsItem = React.createClass({
    });
    NewsItem.jsx
    var React = require('react');
    var NewsAuthor = require('./component/NewsAuthor');
    var NewsTitle = require('./component/NewsTitle');
    var NewsCover = require('./component/NewsCover');
    var NewsStats = require('./component/NewsStats');
    render: function() {
    }
    var post = this.props.post;
    return (






    );

    View Slide

  82. var NewsItem = React.createClass({
    });
    NewsItem.jsx
    var React = require('react');
    var NewsAuthor = require('./component/NewsAuthor');
    var NewsTitle = require('./component/NewsTitle');
    var NewsCover = require('./component/NewsCover');
    var NewsStats = require('./component/NewsStats');
    render: function() {
    }
    var post = this.props.post;
    return (






    );

    View Slide

  83. var NewsItem = React.createClass({
    });
    NewsItem.jsx
    var React = require('react');
    var NewsAuthor = require('./component/NewsAuthor');
    var NewsTitle = require('./component/NewsTitle');
    var NewsCover = require('./component/NewsCover');
    var NewsStats = require('./component/NewsStats');
    render: function() {
    }
    var post = this.props.post;
    return (


    );




    received data
    from NewsFeed

    View Slide

  84. var NewsItem = React.createClass({
    });
    NewsItem.jsx
    var React = require('react');
    var NewsAuthor = require('./component/NewsAuthor');
    var NewsTitle = require('./component/NewsTitle');
    var NewsCover = require('./component/NewsCover');
    var NewsStats = require('./component/NewsStats');
    render: function() {
    }
    var post = this.props.post;
    return (


    );




    breaking data to
    each component
    via props

    View Slide

  85. NewsTitle.jsx
    var NewsTitle = React.createClass({
    render: function() {
    var createdAt = this.props.title.createdAt;
    var value = this.props.title.value;
    return (

    {createdAt}
    {value}

    );
    }
    });

    View Slide

  86. NewsTitle.jsx
    var NewsTitle = React.createClass({
    render: function() {
    var createdAt = this.props.title.createdAt;
    var value = this.props.title.value;
    return (

    {createdAt}
    {value}

    );
    }
    });

    {createdAt}
    {value}

    View Slide

  87. your
    browser
    will render…

    View Slide

  88. keeping a good
    semantic

    View Slide

  89. Validating
    props

    View Slide

  90. NewsTitle.jsx
    var NewsTitle = React.createClass({
    propTypes: {
    title: React.PropTypes.object.isRequired
    },
    render: function() {
    var createdAt = this.props.title.createdAt;
    var value = this.props.title.value;
    return (

    {createdAt}
    {value}

    );
    }
    });

    View Slide

  91. NewsTitle.jsx
    var NewsTitle = React.createClass({
    propTypes: {
    title: React.PropTypes.object.isRequired
    },
    render: function() {
    var createdAt = this.props.title.createdAt;
    var value = this.props.title.value;
    return (

    {createdAt}
    {value}

    );
    }
    });
    propTypes: {
    title: React.PropTypes.object.isRequired
    },
    property type
    if is a required
    property
    property name

    View Slide

  92. propTypes: {
    optionalArray: React.PropTypes.array,
    optionalBool: React.PropTypes.bool,
    optionalFunc: React.PropTypes.func,
    optionalNumber: React.PropTypes.number,
    optionalObject: React.PropTypes.object,
    optionalString: React.PropTypes.string,
    ...
    },
    http:/
    /bit.ly/reusable-components
    a bunch of types and options

    View Slide

  93. Generate a manifest of your component
    Throw exceptions when passed a invalid prop
    USEFULLfor

    View Slide

  94. States
    and about

    View Slide

  95. NewsItem.jsx
    var NewsItem = React.createClass({
    getInitialState: function() {
    return { isBookmarked: false };
    },
    handleSelect: function(e) {
    this.setState({ isBookmarked: true });
    e.preventDefault();
    },
    render: function() {
    var post = this.props.post;
    return (






    );
    }
    });

    View Slide

  96. NewsItem.jsx
    var NewsItem = React.createClass({
    getInitialState: function() {
    return { isBookmarked: false };
    },
    handleSelect: function(e) {
    this.setState({ isBookmarked: true });
    e.preventDefault();
    },
    render: function() {
    var post = this.props.post;
    return (






    );
    }
    });
    getInitialState: function() {
    return { isBookmarked: false };
    },

    View Slide

  97. NewsItem.jsx
    var NewsItem = React.createClass({
    getInitialState: function() {
    return { isBookmarked: false };
    },
    handleSelect: function(e) {
    this.setState({ isBookmarked: true });
    e.preventDefault();
    },
    render: function() {
    var post = this.props.post;
    return (






    );
    }
    });
    handleSelect: function(e) {
    this.setState({ isBookmarked: true });
    e.preventDefault();
    },

    View Slide

  98. NewsItem.jsx
    var NewsItem = React.createClass({
    getInitialState: function() {
    return { isBookmarked: false };
    },
    handleSelect: function(e) {
    this.setState({ isBookmarked: true });
    e.preventDefault();
    },
    render: function() {
    var post = this.props.post;
    return (






    );
    }
    });
    onClick={this.handleSelect}

    View Slide

  99. NewsItem.jsx
    var NewsItem = React.createClass({
    getInitialState: function() {
    return { isBookmarked: false };
    },
    handleSelect: function(e) {
    this.setState({ isBookmarked: true });
    e.preventDefault();
    },
    render: function() {
    var post = this.props.post;
    return (






    );
    }
    });
    onClick={this.handleSelect}
    handleSelect: function(e) {
    this.setState({ isBookmarked: true });
    e.preventDefault();
    },
    getInitialState: function() {
    return { isBookmarked: false };
    },
    managing
    state

    View Slide

  100. this.setState();
    VirtualDOM
    will re-render on each

    View Slide

  101. var React = require('react');
    var NewsFeed = require('./components/NewsFeed');
    var posts = $.ajax('GET', '/some/api/url/post');
    posts.success(function(response) {
    React.render(
    ,
    document.getElementById('#myDomNode')
    );
    });
    main.jsx

    View Slide

  102. var React = require('react');
    var NewsFeed = require('./components/NewsFeed');
    var posts = $.ajax('GET', '/some/api/url/post');
    posts.success(function(response) {
    React.render(
    ,
    document.getElementById('#myDomNode')
    );
    });
    main.jsx
    posts.success(function(response) {
    });
    var posts = $.ajax('GET', '/some/api/url/post');

    View Slide

  103. var React = require('react');
    var NewsFeed = require('./components/NewsFeed');
    var posts = $.ajax('GET', '/some/api/url/post');
    posts.success(function(response) {
    React.render(
    ,
    document.getElementById('#myDomNode')
    );
    });
    main.jsx
    React.render(
    ,
    document.getElementById('#myDomNode')
    );

    View Slide

  104. Life
    Cycle
    component

    View Slide

  105. LifeCycle
    component
    Callbacks that become possible to
    interact with Virtual DOM and
    manipulate the real DOM

    View Slide

  106. mounting unmounting
    updating
    componentWillMount()
    componentDidMount()
    componentWillUnmount()
    componentWillReceiveProps(nextProps)
    shouldComponentUpdate(nextProps, nextState)
    componentWillUpdate(nextProps, nextState)
    componentDidUpdate(prevProps, prevState)

    View Slide

  107. Manage state of your component
    USEFULLfor
    Manage virtual dom render updates
    Integrate third-party scripts

    View Slide

  108. var Slider = React.createClass({
    render: function() {
    return (

    ...
    ...
    ...
    ...

    );
    },
    componentDidMount: function () {
    var sliderNode = this.getDOMNode();
    $(sliderNode).sliderPlugin();
    }
    });
    Slider.jsx

    View Slide

  109. var Slider = React.createClass({
    render: function() {
    return (

    ...
    ...
    ...
    ...

    );
    },
    componentDidMount: function () {
    var sliderNode = this.getDOMNode();
    $(sliderNode).sliderPlugin();
    }
    });
    Slider.jsx
    componentDidMount: function () {
    var sliderNode = this.getDOMNode();
    $(sliderNode).sliderPlugin();
    }

    View Slide

  110. var Slider = React.createClass({
    render: function() {
    return (

    ...
    ...
    ...
    ...

    );
    },
    componentDidMount: function () {
    var sliderNode = this.getDOMNode();
    $(sliderNode).sliderPlugin();
    }
    });
    Slider.jsx
    var sliderNode = this.getDOMNode();

    ...
    ...
    ...
    ...

    View Slide

  111. var Slider = React.createClass({
    render: function() {
    return (

    ...
    ...
    ...
    ...

    );
    },
    componentDidMount: function () {
    var sliderNode = this.getDOMNode();
    $(sliderNode).sliderPlugin();
    }
    });
    Slider.jsx
    $(sliderNode).sliderPlugin();

    View Slide

  112. Mixins

    View Slide

  113. Snippets of reusable code that can
    be injected on your component
    without modifying it's main behavior
    Mixins

    View Slide

  114. var NewsStats = React.createClass({
    render: function() {
    // some stuff
    },
    checkIfAuthenticated: function() {
    if (MyData.isAuthenticated()) {
    this.setState({ isAuth: true });
    }
    }
    });
    NewsStats.jsx
    var NewsAuthor = React.createClass({
    render: function() {
    // some stuff
    },
    checkIfAuthenticated: function() {
    if (MyData.isAuthenticated()) {
    this.setState({ isAuth: true });
    }
    }
    });

    View Slide

  115. var NewsStats = React.createClass({
    render: function() {
    // some stuff
    },
    checkIfAuthenticated: function() {
    if (MyData.isAuthenticated()) {
    this.setState({ isAuth: true });
    }
    }
    });
    NewsStats.jsx
    var NewsAuthor = React.createClass({
    render: function() {
    // some stuff
    },
    checkIfAuthenticated: function() {
    if (MyData.isAuthenticated()) {
    this.setState({ isAuth: true });
    }
    }
    });
    checkIfAuthenticated: function() {
    if (MyData.isAuthenticated()) {
    this.setState({ isAuth: true });
    }
    }
    checkIfAuthenticated: function() {
    if (MyData.isAuthenticated()) {
    this.setState({ isAuth: true });
    }
    }
    we need to
    be DRY here

    View Slide

  116. AuthMixin.jsx
    var AuthMixin = {
    getInitialState: function() {
    return { isAuth: false };
    },
    checkIfAuthenticated: function() {
    if (MyData.isAuthenticated()) {
    this.setState({ isAuth: true });
    }
    }
    };

    View Slide

  117. AuthMixin.jsx
    var AuthMixin = {
    getInitialState: function() {
    return { isAuth: false };
    },
    checkIfAuthenticated: function() {
    if (MyData.isAuthenticated()) {
    this.setState({ isAuth: true });
    }
    }
    };
    var AuthMixin = {
    };

    View Slide

  118. AuthMixin.jsx
    var AuthMixin = {
    getInitialState: function() {
    return { isAuth: false };
    },
    checkIfAuthenticated: function() {
    if (MyData.isAuthenticated()) {
    this.setState({ isAuth: true });
    }
    }
    };
    checkIfAuthenticated: function() {
    if (MyData.isAuthenticated()) {
    this.setState({ isAuth: true });
    }
    }

    View Slide

  119. AuthMixin.jsx
    var AuthMixin = {
    getInitialState: function() {
    return { isAuth: false };
    },
    checkIfAuthenticated: function() {
    if (MyData.isAuthenticated()) {
    this.setState({ isAuth: true });
    }
    }
    };
    getInitialState: function() {
    return { isAuth: false };
    },

    View Slide

  120. NewsAuthor.jsx
    var AuthMixin = require('./mixins/AuthMixin');
    var NewsAuthor = React.createClass({
    mixins: [AuthMixin],
    render: function() {
    this.checkIfAuthenticated();
    }
    });

    View Slide

  121. NewsAuthor.jsx
    var AuthMixin = require('./mixins/AuthMixin');
    var NewsAuthor = React.createClass({
    mixins: [AuthMixin],
    render: function() {
    this.checkIfAuthenticated();
    }
    });
    var AuthMixin = require('./mixins/AuthMixin');

    View Slide

  122. NewsAuthor.jsx
    var AuthMixin = require('./mixins/AuthMixin');
    var NewsAuthor = React.createClass({
    mixins: [AuthMixin],
    render: function() {
    this.checkIfAuthenticated();
    }
    });
    var NewsAuthor = React.createClass({
    mixins: [AuthMixin],
    });

    View Slide

  123. NewsAuthor.jsx
    var AuthMixin = require('./mixins/AuthMixin');
    var NewsAuthor = React.createClass({
    mixins: [AuthMixin],
    render: function() {
    this.checkIfAuthenticated();
    }
    });
    render: function() {
    this.checkIfAuthenticated();
    }

    View Slide

  124. Server
    Render

    View Slide

  125. Render your component both on server
    and client, making your application
    Isomorphic and and crawlable.
    ServerRender

    View Slide

  126. View layer
    Rounting/Controller
    Application Logic
    Client
    Server
    SPA
    Form
    Validation
    DOM
    Manipulation
    Animations
    Persistence via API

    View Slide

  127. Isomorphic
    Client
    Server
    SPA
    Form
    Validation
    DOM
    Manipulation
    Animations
    View layer
    Persistence via API
    Rounting/Controller
    Application Logic

    View Slide

  128. Client
    Server
    Render static
    markup
    via server
    Attach
    components
    behavior
    Render

    View Slide

  129. var React = require('react');
    var NewsFeed = require('./components/NewFeed');
    var posts = api.fetchPosts();
    var html = React.renderToString(

    );
    server.renderHtml(html);
    server.js

    View Slide

  130. var React = require('react');
    var NewsFeed = require('./components/NewFeed');
    var posts = api.fetchPosts();
    var html = React.renderToString(

    );
    server.renderHtml(html);
    server.js
    var React = require('react');
    var NewsFeed = require('./components/NewFeed');
    var posts = api.fetchPosts();

    View Slide

  131. var React = require('react');
    var NewsFeed = require('./components/NewFeed');
    var posts = api.fetchPosts();
    var html = React.renderToString(

    );
    server.renderHtml(html);
    server.js
    var html = React.renderToString(

    );

    View Slide

  132. var React = require('react');
    var NewsFeed = require('./components/NewFeed');
    var posts = api.fetchPosts();
    var html = React.renderToString(

    );
    server.renderHtml(html);
    server.js
    server.renderHtml(html); // just to illustrate

    View Slide

  133. View Slide

  134. in a
    nutshell
    React introduces a new way to build
    scalable applications that can take
    you out of your comfort zone

    View Slide

  135. in a
    nutshell
    You need to clean your mind
    about a lot of old "trues"

    View Slide

  136. in a
    nutshell
    It’s about deliver value.
    If something help you to make that.
    Why do you worry about write your
    HTML inside Javascript?

    View Slide

  137. I hope you
    enjoyed

    View Slide

  138. Pedro Nauck
    FRONTEND DEVELOPER
    @pedronauck
    pedronauck.com

    View Slide

  139. Questions?

    View Slide