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

React: Thinking State First

9cde37f47e4a800ea081ea42de8d749a?s=47 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

9cde37f47e4a800ea081ea42de8d749a?s=128

Doug Neiner

October 23, 2015
Tweet

Transcript

  1. React: Thinking State First Doug Neiner

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

  4. React: Thinking State First Doug Neiner

  5. Why another library? Why should I care?

  6. Why React.js? • Cohesive Templates and Code • Enforced Predictable

    Behavior • Synthetic Event System • Performance • Can be integrated gradually
  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?
  8. JavaScript var ct = document.querySelector( ".cart-count" ); ct.innerHTML = "5";

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

  10. jQuery $.each( someArray, function ( item ) { $( "#cart-items"

    ).append( "<li class='cart-item'>" + item.title + "</li>" ); } );
  11. jQuery var $ul = $( "<ul/>" ); $.each( someArray, function

    ( item ) { $ul.append( $( "<li />", { "class": "cart-item", text: item.title } ) ); } ); $container.html( $ul );
  12. Rinse. Repeat. We need a better way

  13. Templates <ul> <% _.each( items, function ( item ) {

    %> <li class="cart-item"><%- item.title %></li> <% } ) %> </ul>
  14. Templates • When do you render them? • How often?

    • How do you get data out 
 of the rendered DOM?
  15. Too Much Thinking We need a better way

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

  17. These Tools Are Solving The 
 Same Problem

  18. The “Template” Part • Special attributes: data-bind, ng-repeat • Learning

    template syntax: {{#each}} • Templates maintained separately from the
 code that uses them…
  19. Templates maintained separately from the code that uses them…

  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)
  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)
  22. A React Component (JSX) React.createClass({ render: function() { return <div

    className="cart"> <span className="cart-count"> { this.props.items.length } </span> <CartItems items={ this.props.items } /> </div>; } })
  23. A React Component (JSX) React.createClass({ render: function() { return <div

    className="cart"> <span className="cart-count"> { this.props.items.length } </span> <CartItems items={ this.props.items } /> </div>; } })
  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 } ) ); } });
  25. The “Template” Part • Special attributes: key, ref • Learning

    template syntax: {} + JS • Templates maintained with the code that 
 uses them.
  26. Cohesion between our code and our templates in a language

    we already use. Key Benefit
  27. Predictable Behavior Kindly Enforced by React.js

  28. Props State Options Attributes Variables

  29. Props State Externally
 Controlled Internally
 Controlled

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

    the same thing. Every time.
  31. Props in Action <NewsItem title="Welcome" content="..." /> var NewsItem =

    React.createClass({ render: function() { return ( <div className="newsItem"> <h2>{ this.props.title }</h2> <p>{ this.props.content }</p> </div> ); } });
  32. Props in Action <NewsItem title="Welcome" content="..." /> var NewsItem =

    React.createClass({ render: function() { return ( <div className="newsItem"> <h2>{ this.props.title }</h2> <p>{ this.props.content }</p> </div> ); } });
  33. State in Action var Menu = React.createClass( { getInitialState: function

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

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

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

    () { return { open: false }; }, toggleOpen: function() { this.setState({ open: !this.state.open }); }, ... render: function() { return <div onClick={ this.toggleOpen }> { this.state.open ? "Open" : "Closed" } </div>; } } );
  37. Any time props or state change, the component will call

    render. 
 Every time. (Default Behavior)
  38. Uh… That's predictable

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

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


    to reflect the changes
  41. Changes Flow
 One Direction

  42. Changes Flow Down <NewsApp> <UnreadCount /> <NewsList> <NewsItem>

  43. <NewsApp> <UnreadCount /> <NewsList> <NewsItem> this.setState({
 items: items,
 unread: itemIds


    }) Changes Flow Down
  44. <NewsApp> <UnreadCount count={…}/> <NewsList> <NewsItem> Changes Flow Down

  45. <NewsApp> <UnreadCount /> <NewsList items={…}> <NewsItem> Changes Flow Down

  46. <NewsApp> <UnreadCount /> <NewsList> <NewsItem {…item} unread={…}> Changes Flow Down

  47. <NewsApp> <UnreadCount /> <NewsList> <NewsItem> Changes Flow Down When clicked,

    reduce 
 UnreadCount by 1 and remove my class
 "is-unread"
  48. <NewsApp> <UnreadCount /> <NewsList> <NewsItem> Changes Flow Down When clicked,

    reduce 
 UnreadCount by 1 and remove my class
 "is-unread" ◦
  49. <NewsApp> <UnreadCount /> <NewsList> <NewsItem> Changes Flow Down When clicked,

    call
 this.props.newsItemRead( id )
  50. <NewsApp> <UnreadCount /> <NewsList> <NewsItem> Changes Flow Down When clicked,

    publish("newsItemRead", id );
  51. <NewsApp> <UnreadCount /> <NewsList> <NewsItem> Changes Flow Down this.setState({
 unread:

    itemIds
 })
  52. A coding pattern that produces predictable components without sacrificing performance

    Key Benefit
  53. I'll Say Yes To 
 Another Library But what does

    my 
 commitment look like?
  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
  55. A focused library that can be integrated gradually. Key Benefit

  56. Still Not Convinced? • Accessibility • Server side rendering •

    Other rendering engines • Touch support • React Developer Tools
  57. I'll Say No To 
 Another Library So what advice

    do you
 have for me?
  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.
  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.
  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 )
  61. Have a Single Owner • Never have two separate pieces

    of JavaScript modifying the same aspect of a DOM element (style, children, etc)
  62. Thank You doug@leankit.com @dougneiner