ReactJS: Keep Simple. Everything can be a component!

Af6a12710770ad9a7cfd08c97efd40d3?s=47 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.

Af6a12710770ad9a7cfd08c97efd40d3?s=128

Pedro Nauck

November 22, 2014
Tweet

Transcript

  1. Component KEEP SIMPLE everything can be a it

  2. Pedro Nauck FRONTEND DEVELOPER @pedronauck pedronauck.com

  3. USER Interfaces

  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. “
  5. But, what WEOUR customers want?

  6. find Value

  7. we need to deliver that Value

  8. it's just about Design not

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

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

  11. complexity project size

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

    everyone “
  13. when become complex ? a project

  14. questions answers

  15. Is  this  a  module  or  not? “

  16. Do  I  need  a  directive  here? “

  17. Should  I  create  a   factory  or  a  service? “

  18. Why  this  shit  doesn’t  work? “

  19. None
  20. complexity value

  21. React how can help us with that?

  22. Javascript Library for building UI

  23. ≄ library framework

  24. library framework A tool to resolve just one specific thing

    A set of tools to resolve a lot of things
  25. library framework

  26. is using? who

  27. the real proposal around

  28. PROCESS simple! DEVELOPMENT is making your

  29. how?

  30. 1 #

  31. without mutation

  32. without mutation We need a lightweight DOM We need control

    over our data We need to know what’s happening
  33. WE Don't NEED

  34. None
  35. 2 #

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

  37. FOCUS ON Components your

  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
  39. None
  40. <NewsFeed>

  41. <NewsItem>

  42. <NewsAuthor> <NewsTitle> <NewsCover> <NewsStats>

  43. this is the concept just

  44. SHOW ME some code please!

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

    var React = require('react'); return ( <article className='news-item'> <div className='news-author'>...</div> <header className='news-title'>...</header> <figure className=‘news-cover'>...</figure> <ul className='news-stats'>...</ul> </article> );
  46. NewsItem.jsx var NewsItem = React.createClass({ }); render: function() { }

    var React = require('react'); return ( <article className='news-item'> <div className='news-author'>...</div> <header className='news-title'>...</header> <figure className=‘news-cover'>...</figure> <ul className='news-stats'>...</ul> </article> );
  47. NewsItem.jsx var NewsItem = React.createClass({ }); render: function() { }

    var React = require('react'); return ( <article className='news-item'> <div className='news-author'>...</div> <header className='news-title'>...</header> <figure className=‘news-cover'>...</figure> <ul className='news-stats'>...</ul> </article> ); factory pattern
  48. NewsItem.jsx var NewsItem = React.createClass({ }); render: function() { }

    var React = require('react'); return ( <article className='news-item'> <div className='news-author'>...</div> <header className='news-title'>...</header> <figure className=‘news-cover'>...</figure> <ul className='news-stats'>...</ul> </article> );
  49. NewsItem.jsx var NewsItem = React.createClass({ }); render: function() { }

    var React = require('react'); return ( <article className='news-item'> <div className='news-author'>...</div> <header className='news-title'>...</header> <figure className=‘news-cover'>...</figure> <ul className='news-stats'>...</ul> </article> );
  50. NewsItem.jsx var NewsItem = React.createClass({ }); render: function() { }

    var React = require('react'); return ( <article className='news-item'> <div className='news-author'>...</div> <header className='news-title'>...</header> <figure className=‘news-cover'>...</figure> <ul className='news-stats'>...</ul> </article> );
  51. None
  52. JSX A Javascript XML based extension that compile just the

    template part of your code
  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. “
  54. It makes a lot of sense that a JavaScript's template

    stays in the JavaScript “ @jcemer
  55. What's the difference? 1 # the concerns are mixing too

    <article className='news-item'> <div className=‘news-author’> <%= @post.author.name %> </div> <header className=‘news-title'> <%= @post.title %> </header> <div className='news-cover'> <%= image_tag @post.image %> </div> </article>
  56. to much better than var title = 'Some title'; var

    author = 'Jim Keneddy'; var newsItem = '<article class="news-item">' + '<div class="news-author">' + author + '</div>' + '<header class="news-title">' + title + '</header>' + '<div class="news-cover">' + '...' + '</div>' + '<ul class="news-stats"> + '...' + </ul>' + '</article>'; 2 #
  57. var NewsItem = React.createClass({ }); render: function() { } var

    React = require('react'); return ( <article className='news-item'> <div className='news-author'>...</div> <header className='news-title'>...</header> <figure className=‘news-cover'>...</figure> <ul className='news-stats'>...</ul> </article> ); Will BE Compiled 3 # NewsItem.jsx
  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'}, '...') ) ) );
  59. But Why?

  60. because is mutation EVIL

  61. Virtual DOM

  62. An object tree that is a representation of the DOM.

    Kinda a "mirror". Virtual DOM
  63. Travolta DOM

  64. VirtualDOM ParentComponent ChildComponent ChildComponent ChildComponent ChildComponent ChildComponent

  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
  66. Old Tree Mutations New Tree VirtualDOM

  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
  68. Advantages: Javascript is Fast and the DOM is slow

  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
  70. None
  71. return ( <article className='news-item'> <div className='news-author'>...</div> <header className='news-title'>...</header> <figure className='news-cover'>

    ... <ul className='news-stats'>...</ul> </figure> </article> ); NewsItem.jsx kinda messy! render: function() { }
  72. WE NEED break to

  73. State & Props

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

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

    be mutable
  76. Uniderectional DataFlow

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

    their own state (via state)
  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 <NewsItem post={post} key={post._id} /> }); return <div className='news-feed'>{posts}</div> } }); NewsFeed.jsx
  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 <NewsItem post={post} key={post._id} /> }); return <div className='news-feed'>{posts}</div> } }); NewsFeed.jsx var posts = this.props.posts.map(function(post) { return <NewsItem post={post} key={post._id} /> }); return <div className='news-feed'>{posts}</div> var NewsItem = require('./components/NewsItem');
  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 <NewsItem post={post} key={post._id} /> }); return <div className='news-feed'>{posts}</div> } }); NewsFeed.jsx post={post}
  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 ( <article className='news-item'> <NewsAuthor author={post.author} /> <NewsTitle title={post.title} /> <NewsCover image={post.cover} /> <NewsStats postStats={post.stats} /> </article> );
  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 ( <article className='news-item'> <NewsAuthor author={post.author} /> <NewsTitle title={post.title} /> <NewsCover image={post.cover} /> <NewsStats postStats={post.stats} /> </article> );
  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 ( <article className='news-item'> </article> ); <NewsAuthor author={post.author} /> <NewsTitle title={post.title} /> <NewsCover image={post.cover} /> <NewsStats postStats={post.stats} /> received data from NewsFeed
  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 ( <article className='news-item'> </article> ); <NewsAuthor author={post.author} /> <NewsTitle title={post.title} /> <NewsCover image={post.cover} /> <NewsStats postStats={post.stats} /> breaking data to each component via props
  85. NewsTitle.jsx var NewsTitle = React.createClass({ render: function() { var createdAt

    = this.props.title.createdAt; var value = this.props.title.value; return ( <header className='news-title'> <span className='news-title-data'>{createdAt}</span> <h2 className='news-title-value'>{value}</h2> </header> ); } });
  86. NewsTitle.jsx var NewsTitle = React.createClass({ render: function() { var createdAt

    = this.props.title.createdAt; var value = this.props.title.value; return ( <header className='news-title'> <span className='news-title-data'>{createdAt}</span> <h2 className='news-title-value'>{value}</h2> </header> ); } }); <header className='news-title'> <span className='news-title-data'>{createdAt}</span> <h2 className='news-title-value'>{value}</h2> </header>
  87. your browser will render…

  88. keeping a good semantic

  89. Validating props

  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 ( <header className='news-title'> <span className='news-title-data'>{createdAt}</span> <h2 className='news-title-value'>{value}</h2> </header> ); } });
  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 ( <header className='news-title'> <span className='news-title-data'>{createdAt}</span> <h2 className='news-title-value'>{value}</h2> </header> ); } }); propTypes: { title: React.PropTypes.object.isRequired }, property type if is a required property property name
  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
  93. Generate a manifest of your component Throw exceptions when passed

    a invalid prop USEFULLfor
  94. States and about

  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 ( <article className='news-item' onClick={this.handleSelect}> <NewsAuthor author={post.author} /> <NewsTitle title={post.title} /> <NewsCover image={post.cover} /> <NewsStats postStats={post.stats} /> </article> ); } });
  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 ( <article className='news-item' onClick={this.handleSelect}> <NewsAuthor author={post.author} /> <NewsTitle title={post.title} /> <NewsCover image={post.cover} /> <NewsStats postStats={post.stats} /> </article> ); } }); getInitialState: function() { return { isBookmarked: false }; },
  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 ( <article className='news-item' onClick={this.handleSelect}> <NewsAuthor author={post.author} /> <NewsTitle title={post.title} /> <NewsCover image={post.cover} /> <NewsStats postStats={post.stats} /> </article> ); } }); handleSelect: function(e) { this.setState({ isBookmarked: true }); e.preventDefault(); },
  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 ( <article className='news-item' onClick={this.handleSelect}> <NewsAuthor author={post.author} /> <NewsTitle title={post.title} /> <NewsCover image={post.cover} /> <NewsStats postStats={post.stats} /> </article> ); } }); onClick={this.handleSelect}
  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 ( <article className='news-item' onClick={this.handleSelect}> <NewsAuthor author={post.author} /> <NewsTitle title={post.title} /> <NewsCover image={post.cover} /> <NewsStats postStats={post.stats} /> </article> ); } }); onClick={this.handleSelect} handleSelect: function(e) { this.setState({ isBookmarked: true }); e.preventDefault(); }, getInitialState: function() { return { isBookmarked: false }; }, managing state
  100. this.setState(); VirtualDOM will re-render on each

  101. var React = require('react'); var NewsFeed = require('./components/NewsFeed'); var posts

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

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

    = $.ajax('GET', '/some/api/url/post'); posts.success(function(response) { React.render( <NewsFeed posts={response.body.posts} />, document.getElementById('#myDomNode') ); }); main.jsx React.render( <NewsFeed posts={response.body.posts} />, document.getElementById('#myDomNode') );
  104. Life Cycle component

  105. LifeCycle component Callbacks that become possible to interact with Virtual

    DOM and manipulate the real DOM
  106. mounting unmounting updating componentWillMount() componentDidMount() componentWillUnmount() componentWillReceiveProps(nextProps) shouldComponentUpdate(nextProps, nextState) componentWillUpdate(nextProps,

    nextState) componentDidUpdate(prevProps, prevState)
  107. Manage state of your component USEFULLfor Manage virtual dom render

    updates Integrate third-party scripts
  108. var Slider = React.createClass({ render: function() { return ( <ul

    className='slider'> <li className='slider-items'>...</li> <li className='slider-items'>...</li> <li className='slider-items'>...</li> <li className='slider-items'>...</li> </ul> ); }, componentDidMount: function () { var sliderNode = this.getDOMNode(); $(sliderNode).sliderPlugin(); } }); Slider.jsx
  109. var Slider = React.createClass({ render: function() { return ( <ul

    className='slider'> <li className='slider-items'>...</li> <li className='slider-items'>...</li> <li className='slider-items'>...</li> <li className='slider-items'>...</li> </ul> ); }, componentDidMount: function () { var sliderNode = this.getDOMNode(); $(sliderNode).sliderPlugin(); } }); Slider.jsx componentDidMount: function () { var sliderNode = this.getDOMNode(); $(sliderNode).sliderPlugin(); }
  110. var Slider = React.createClass({ render: function() { return ( <ul

    className='slider'> <li className='slider-items'>...</li> <li className='slider-items'>...</li> <li className='slider-items'>...</li> <li className='slider-items'>...</li> </ul> ); }, componentDidMount: function () { var sliderNode = this.getDOMNode(); $(sliderNode).sliderPlugin(); } }); Slider.jsx var sliderNode = this.getDOMNode(); <ul className='slider'> <li className='slider-items'>...</li> <li className='slider-items'>...</li> <li className='slider-items'>...</li> <li className='slider-items'>...</li> </ul>
  111. var Slider = React.createClass({ render: function() { return ( <ul

    className='slider'> <li className='slider-items'>...</li> <li className='slider-items'>...</li> <li className='slider-items'>...</li> <li className='slider-items'>...</li> </ul> ); }, componentDidMount: function () { var sliderNode = this.getDOMNode(); $(sliderNode).sliderPlugin(); } }); Slider.jsx $(sliderNode).sliderPlugin();
  112. Mixins

  113. Snippets of reusable code that can be injected on your

    component without modifying it's main behavior Mixins
  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 }); } } });
  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
  116. AuthMixin.jsx var AuthMixin = { getInitialState: function() { return {

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

    isAuth: false }; }, checkIfAuthenticated: function() { if (MyData.isAuthenticated()) { this.setState({ isAuth: true }); } } }; var AuthMixin = { };
  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 }); } }
  119. AuthMixin.jsx var AuthMixin = { getInitialState: function() { return {

    isAuth: false }; }, checkIfAuthenticated: function() { if (MyData.isAuthenticated()) { this.setState({ isAuth: true }); } } }; getInitialState: function() { return { isAuth: false }; },
  120. NewsAuthor.jsx var AuthMixin = require('./mixins/AuthMixin'); var NewsAuthor = React.createClass({ mixins:

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

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

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

    [AuthMixin], render: function() { this.checkIfAuthenticated(); } }); render: function() { this.checkIfAuthenticated(); }
  124. Server Render

  125. Render your component both on server and client, making your

    application Isomorphic and and crawlable. ServerRender
  126. View layer Rounting/Controller Application Logic Client Server SPA Form Validation

    DOM Manipulation Animations Persistence via API
  127. Isomorphic Client Server SPA Form Validation DOM Manipulation Animations View

    layer Persistence via API Rounting/Controller Application Logic
  128. Client Server Render static markup via server Attach components behavior

    Render
  129. var React = require('react'); var NewsFeed = require('./components/NewFeed'); var posts

    = api.fetchPosts(); var html = React.renderToString( <NewsFeed posts={posts} /> ); server.renderHtml(html); server.js
  130. var React = require('react'); var NewsFeed = require('./components/NewFeed'); var posts

    = api.fetchPosts(); var html = React.renderToString( <NewsFeed posts={posts} /> ); server.renderHtml(html); server.js var React = require('react'); var NewsFeed = require('./components/NewFeed'); var posts = api.fetchPosts();
  131. var React = require('react'); var NewsFeed = require('./components/NewFeed'); var posts

    = api.fetchPosts(); var html = React.renderToString( <NewsFeed posts={posts} /> ); server.renderHtml(html); server.js var html = React.renderToString( <NewsFeed posts={posts} /> );
  132. var React = require('react'); var NewsFeed = require('./components/NewFeed'); var posts

    = api.fetchPosts(); var html = React.renderToString( <NewsFeed posts={posts} /> ); server.renderHtml(html); server.js server.renderHtml(html); // just to illustrate
  133. None
  134. in a nutshell React introduces a new way to build

    scalable applications that can take you out of your comfort zone
  135. in a nutshell You need to clean your mind about

    a lot of old "trues"
  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?
  137. I hope you enjoyed

  138. Pedro Nauck FRONTEND DEVELOPER @pedronauck pedronauck.com

  139. Questions?