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. 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. “
  2. 19.
  3. 24.

    library framework A tool to resolve just one specific thing

    A set of tools to resolve a lot of things
  4. 29.
  5. 30.

    1 #

  6. 32.

    without mutation We need a lightweight DOM We need control

    over our data We need to know what’s happening
  7. 34.
  8. 35.

    2 #

  9. 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
  10. 39.
  11. 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> );
  12. 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> );
  13. 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
  14. 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> );
  15. 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> );
  16. 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> );
  17. 51.
  18. 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. “
  19. 54.

    It makes a lot of sense that a JavaScript's template

    stays in the JavaScript “ @jcemer
  20. 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>
  21. 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 #
  22. 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
  23. 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'}, '...') ) ) );
  24. 59.
  25. 62.
  26. 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
  27. 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
  28. 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
  29. 70.
  30. 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() { }
  31. 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
  32. 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');
  33. 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}
  34. 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> );
  35. 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> );
  36. 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
  37. 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
  38. 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> ); } });
  39. 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>
  40. 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> ); } });
  41. 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
  42. 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
  43. 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> ); } });
  44. 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 }; },
  45. 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(); },
  46. 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}
  47. 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
  48. 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
  49. 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');
  50. 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') );
  51. 107.
  52. 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
  53. 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(); }
  54. 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>
  55. 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();
  56. 112.
  57. 113.

    Snippets of reusable code that can be injected on your

    component without modifying it's main behavior Mixins
  58. 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 }); } } });
  59. 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
  60. 116.

    AuthMixin.jsx var AuthMixin = { getInitialState: function() { return {

    isAuth: false }; }, checkIfAuthenticated: function() { if (MyData.isAuthenticated()) { this.setState({ isAuth: true }); } } };
  61. 117.

    AuthMixin.jsx var AuthMixin = { getInitialState: function() { return {

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

    AuthMixin.jsx var AuthMixin = { getInitialState: function() { return {

    isAuth: false }; }, checkIfAuthenticated: function() { if (MyData.isAuthenticated()) { this.setState({ isAuth: true }); } } }; getInitialState: function() { return { isAuth: false }; },
  64. 120.

    NewsAuthor.jsx var AuthMixin = require('./mixins/AuthMixin'); var NewsAuthor = React.createClass({ mixins:

    [AuthMixin], render: function() { this.checkIfAuthenticated(); } });
  65. 121.

    NewsAuthor.jsx var AuthMixin = require('./mixins/AuthMixin'); var NewsAuthor = React.createClass({ mixins:

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

    NewsAuthor.jsx var AuthMixin = require('./mixins/AuthMixin'); var NewsAuthor = React.createClass({ mixins:

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

    NewsAuthor.jsx var AuthMixin = require('./mixins/AuthMixin'); var NewsAuthor = React.createClass({ mixins:

    [AuthMixin], render: function() { this.checkIfAuthenticated(); } }); render: function() { this.checkIfAuthenticated(); }
  68. 125.

    Render your component both on server and client, making your

    application Isomorphic and and crawlable. ServerRender
  69. 126.
  70. 127.

    Isomorphic Client Server SPA Form Validation DOM Manipulation Animations View

    layer Persistence via API Rounting/Controller Application Logic
  71. 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
  72. 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();
  73. 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} /> );
  74. 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
  75. 133.
  76. 134.

    in a nutshell React introduces a new way to build

    scalable applications that can take you out of your comfort zone
  77. 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?
  78. 139.