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

ReactJS: Keep Simple. Everything can be a compo...

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. 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. library framework A tool to resolve just one specific thing

    A set of tools to resolve a lot of things
  3. 1 #

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

    over our data We need to know what’s happening
  5. 2 #

  6. 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
  7. 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> );
  8. 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> );
  9. 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
  10. 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> );
  11. 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. 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. 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. “
  14. It makes a lot of sense that a JavaScript's template

    stays in the JavaScript “ @jcemer
  15. 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>
  16. 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 #
  17. 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
  18. 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'}, '...') ) ) );
  19. 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
  20. 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
  21. React Angular Time Time 0ms 0.35ms 0.7ms 1.05ms 1.4ms 1.35ms

    0.31ms Render a list with 1500 rows Benchmark
  22. 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() { }
  23. 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
  24. 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');
  25. 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}
  26. 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> );
  27. 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> );
  28. 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
  29. 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
  30. 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> ); } });
  31. 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>
  32. 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> ); } });
  33. 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
  34. 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
  35. 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> ); } });
  36. 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 }; },
  37. 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(); },
  38. 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}
  39. 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
  40. 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
  41. 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');
  42. 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') );
  43. 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
  44. 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(); }
  45. 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>
  46. 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();
  47. Snippets of reusable code that can be injected on your

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

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

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

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

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

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

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

    [AuthMixin], render: function() { this.checkIfAuthenticated(); } }); render: function() { this.checkIfAuthenticated(); }
  58. Render your component both on server and client, making your

    application Isomorphic and and crawlable. ServerRender
  59. Isomorphic Client Server SPA Form Validation DOM Manipulation Animations View

    layer Persistence via API Rounting/Controller Application Logic
  60. 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
  61. 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();
  62. 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} /> );
  63. 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
  64. in a nutshell React introduces a new way to build

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