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

React: Thinking State First

Doug Neiner
October 23, 2015

React: Thinking State First

A high level introduction to key benefits in React.js that are also a hurdle or a mental shift to using React. This was prepared for an audience of front end developers with varying experience with JavaScript.

Lux Mail Example (from demo at end): http://bit.ly/luxmail
Isomorphic Hot Loader I showed: http://bit.ly/1LLUQNn
Isomorphic React lib I should have probably used: http://bit.ly/1Xp4EUV

Doug Neiner

October 23, 2015
Tweet

More Decks by Doug Neiner

Other Decks in Technology

Transcript

  1. React: Thinking State First
    Doug Neiner

    View Slide

  2. View Slide

  3. github.com/LeanKit-Labs
    Open Source Goodness

    View Slide

  4. React: Thinking State First
    Doug Neiner

    View Slide

  5. Why another library?
    Why should I care?

    View Slide

  6. Why React.js?
    • Cohesive Templates and Code
    • Enforced Predictable Behavior
    • Synthetic Event System
    • Performance
    • Can be integrated gradually

    View Slide

  7. Our Canvas
    • It can stretch to any size
    • It may behave or appear differently to

    different people
    • It can become a performance bottleneck
    when you mess with it
    • So… how do we dynamically modify this
    canvas?

    View Slide

  8. JavaScript
    var ct = document.querySelector( ".cart-count" );
    ct.innerHTML = "5";

    View Slide

  9. jQuery
    $( ".cart-count" ).text( "5" );

    View Slide

  10. jQuery
    $.each( someArray, function ( item ) {
    $( "#cart-items" ).append(
    "" + item.title + ""
    );
    } );

    View Slide

  11. jQuery
    var $ul = $( "" );
    $.each( someArray, function ( item ) {
    $ul.append(
    $( "", {
    "class": "cart-item", text: item.title
    } )
    );
    } );
    $container.html( $ul );

    View Slide

  12. Rinse. Repeat.
    We need a better way

    View Slide

  13. Templates

    <% _.each( items, function ( item ) { %>
    <%- item.title %>
    <% } ) %>

    View Slide

  14. Templates
    • When do you render them?
    • How often?
    • How do you get data out 

    of the rendered DOM?

    View Slide

  15. Too Much Thinking
    We need a better way

    View Slide

  16. Binding + Templates
    • Knockout.js
    • Ember
    • Angular

    View Slide

  17. These Tools
    Are Solving The 

    Same Problem

    View Slide

  18. The “Template” Part
    • Special attributes: data-bind, ng-repeat
    • Learning template syntax: {{#each}}
    • Templates maintained separately from the

    code that uses them…

    View Slide

  19. Templates maintained separately
    from the code that uses them…

    View Slide

  20. 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.
    Additionally, display logic is often very complex and
    using template languages to express it becomes
    cumbersome. – React Docs (emphasis added)

    View Slide

  21. 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.
    Additionally, display logic is often very complex and
    using template languages to express it becomes
    cumbersome. – React Docs (emphasis added)

    View Slide

  22. A React Component (JSX)
    React.createClass({
    render: function() {
    return

    { this.props.items.length }


    ;
    }
    })

    View Slide

  23. A React Component (JSX)
    React.createClass({
    render: function() {
    return

    { this.props.items.length }


    ;
    }
    })

    View Slide

  24. A React Component (JS)
    React.createClass({
    render: function render() {
    return React.createElement( "div", { className: "cart" },
    React.createElement(
    "span", { className: "cart-count" },
    this.props.items.length
    ),
    React.createElement( CartItems,
    { items: this.props.items } )
    );
    }
    });

    View Slide

  25. The “Template” Part
    • Special attributes: key, ref
    • Learning template syntax: {} + JS
    • Templates maintained with the code that 

    uses them.

    View Slide

  26. Cohesion between our code
    and our templates in a
    language we already use.
    Key Benefit

    View Slide

  27. Predictable Behavior
    Kindly Enforced by React.js

    View Slide

  28. Props State
    Options
    Attributes
    Variables

    View Slide

  29. Props State
    Externally

    Controlled
    Internally

    Controlled

    View Slide

  30. Given the same props
    and state, the component
    will render the same
    thing. Every time.

    View Slide

  31. Props in Action

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

    { this.props.title }
    { this.props.content }

    );
    }
    });

    View Slide

  32. Props in Action

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

    { this.props.title }
    { this.props.content }

    );
    }
    });

    View Slide

  33. State in Action
    var Menu = React.createClass( {
    getInitialState: function () {
    return { open: false };
    },
    toggleOpen: function() {
    this.setState({ open: !this.state.open });
    },
    ...
    render: function() {
    return
    { this.state.open ? "Open" : "Closed" }
    ;
    }
    } );

    View Slide

  34. State in Action
    var Menu = React.createClass( {
    getInitialState: function () {
    return { open: false };
    },
    toggleOpen: function() {
    this.setState({ open: !this.state.open });
    },
    ...
    render: function() {
    return
    { this.state.open ? "Open" : "Closed" }
    ;
    }
    } );

    View Slide

  35. State in Action
    var Menu = React.createClass( {
    getInitialState: function () {
    return { open: false };
    },
    toggleOpen: function() {
    this.setState({ open: !this.state.open });
    },
    ...
    render: function() {
    return
    { this.state.open ? "Open" : "Closed" }
    ;
    }
    } );

    View Slide

  36. State in Action
    var Menu = React.createClass( {
    getInitialState: function () {
    return { open: false };
    },
    toggleOpen: function() {
    this.setState({ open: !this.state.open });
    },
    ...
    render: function() {
    return
    { this.state.open ? "Open" : "Closed" }
    ;
    }
    } );

    View Slide

  37. Any time props or state
    change, the component
    will call render. 

    Every time.
    (Default Behavior)

    View Slide

  38. Uh…
    That's predictable

    View Slide

  39. Virtual DOM
    (aka the part of React.js 

    you have heard of)

    View Slide

  40. State or props change first
    Then the page is update

    to reflect the changes

    View Slide

  41. Changes Flow

    One Direction

    View Slide

  42. Changes Flow Down




    View Slide





  43. this.setState({

    items: items,

    unread: itemIds

    })
    Changes Flow Down

    View Slide





  44. Changes Flow Down

    View Slide





  45. Changes Flow Down

    View Slide





  46. Changes Flow Down

    View Slide





  47. Changes Flow Down
    When clicked, reduce 

    UnreadCount by 1 and
    remove my class

    "is-unread"

    View Slide





  48. Changes Flow Down
    When clicked, reduce 

    UnreadCount by 1 and
    remove my class

    "is-unread"

    View Slide





  49. Changes Flow Down
    When clicked, call

    this.props.newsItemRead( id )

    View Slide





  50. Changes Flow Down
    When clicked,
    publish("newsItemRead", id );

    View Slide





  51. Changes Flow Down
    this.setState({

    unread: itemIds

    })

    View Slide

  52. A coding pattern that
    produces predictable
    components without
    sacrificing performance
    Key Benefit

    View Slide

  53. I'll Say Yes To 

    Another Library
    But what does my 

    commitment look like?

    View Slide

  54. Your Commitment
    • Give control of as little or as much of your
    page as you want.
    • A transpilation step (if you use JSX)
    • Some shims/polyfills if you support IE8

    View Slide

  55. A focused library that can be
    integrated gradually.
    Key Benefit

    View Slide

  56. Still Not Convinced?
    • Accessibility
    • Server side rendering
    • Other rendering engines
    • Touch support
    • React Developer Tools

    View Slide

  57. I'll Say No To 

    Another Library
    So what advice do you

    have for me?

    View Slide

  58. Have a Single Source of Truth
    • Not in the DOM, in JavaScript variables
    • Changes are made first to the variables, then
    the view is updated to reflect the change.

    View Slide

  59. Don’t Make Relative Changes
    • Don’t “add 1” or “subtract 1” when adding or
    removing an item from a cart.
    • Adjust the array of cart items, and update the
    count with the new length of that array.

    View Slide

  60. Don’t Make Relative Changes
    • Don’t call toggleClass, hoping the correct
    class gets added or removed.
    • Store a true or false value in a variable. Invert
    the value when you want to toggle, and then
    call toggleClass( "my-class", myVar )

    View Slide

  61. Have a Single Owner
    • Never have two separate pieces of JavaScript
    modifying the same aspect of a DOM element
    (style, children, etc)

    View Slide

  62. Thank You
    [email protected]
    @dougneiner

    View Slide