{"id":1171,"date":"2015-09-22T06:05:08","date_gmt":"2015-09-22T10:05:08","guid":{"rendered":"http:\/\/blog.agilityfeat.com\/?p=1171"},"modified":"2015-09-22T06:05:08","modified_gmt":"2015-09-22T10:05:08","slug":"using-react-js-and-semantic-ui-to-create-stylish-apps","status":"publish","type":"post","link":"https:\/\/agilityfeatpanama.com\/en\/blog\/2015\/09\/using-react-js-and-semantic-ui-to-create-stylish-apps\/","title":{"rendered":"Using React.js and Semantic UI to Create Stylish Apps"},"content":{"rendered":"<p><script src=\"https:\/\/s3-us-west-2.amazonaws.com\/blogs-scripts\/util\/code-scripts-1.js\"><\/script><\/p>\n<p>I&#8217;ve been playing around for a while with Facebook&#8217;s answer to multi-platform real-time apps, React.js and React Native.<\/p>\n<p>I can say I&#8217;m thoroughly convinced million-user architectures will default to React, JSX, and a flavor of Web Sockets or WebRTC for handling real-time.<\/p>\n<p>Today I&#8217;m going to share with you a nice surprise I got when building a test app with React.js and Semantic UI.<\/p>\n<p>It&#8217;s hard to convey how much of a pain in the butt it can be to use pre-existing Javascript frameworks and libraries along with React.js, simply because of how jelous React is about any and all DOM manipulations.<\/p>\n<p>If you want to successfully build React applications which have a nice look and feel you&#8217;re going to have to resign to the fact that jQuery drop-downs\/accordions\/etc, popular fancy shmancy sliders, and any Javascript-based eye candy module will be incompatible with React right out of the box. I&#8217;ll repeat, from now on React is master of your app and no one else is allowed DOM access. So if you want a fancy calendar, either build it yourself or better yet turn to the React community which is actually incredibly active and have already shared very viable replacements for most popular UI modules.<\/p>\n<p>With this said, if you&#8217;ve ever used Semantic UI, you might be wondering then how I can sit here and write an article about how it fits in with React.js when many of its components rely on Javascript DOM manipulations.<\/p>\n<p>And here-in lies the positive surprising conclusion I arrived to while experimenting&#8230;<\/p>\n<h2>Semantic UI is built mainly on CSS, so Javascript is optional<\/h2>\n<p>That&#8217;s right. All those modals, drop-downs, and what-not, all of them work based off of css classes. Even animations, although we&#8217;ll get to those later on.<\/p>\n<p>The little Javascript used by Semantic is actually just there to turn add and remove classes, making boosts overall performance and actually provides the perfect gateway with which to plug React with this fantastically simple framework.<\/p>\n<p>I&#8217;ll stick to the basics in this post and will be sure to build a working app in the near future.<\/p>\n<h2>Using a Semantic UI modal in a React.js app<\/h2>\n<p>Let&#8217;s say you have an app which displays a button that when clicked displays a modal. On out-dated basic HTML your whole app would look like this:<\/p>\n<pre><code class=\"html\">\n&lt;!doctype html&gt;\n&lt;html lang=\"en\"&gt;\n&lt;head&gt;\n  &lt;meta charset=\"UTF-8\"&gt;\n  &lt;title&gt;Boring Old Modal&lt;\/title&gt;\n  &lt;link rel=\"stylesheet\" href=\"semantic.min.css\"&gt;\n  &lt;script src=\"jquery.min.js\"&gt;&lt;\/script&gt;\n  &lt;script src=\"semantic.min.js\"&gt;&lt;\/script&gt;\n  &lt;script&gt;\n    $(function(){\n      $('.button').click(function(){\n        $('.ui.modal').modal('show');\n      });\n    });\n  &lt;\/script&gt;\n&lt;\/head&gt;\n&lt;body&gt;\n  &lt;div class=\"ui teal button\"&gt;Show Modal&lt;\/div&gt;\n  &lt;div class=\"ui small modal\"&gt;\n    &lt;div class=\"ui center aligned header\"&gt;Hello&lt;\/div&gt;\n    &lt;div class=\"content\"&gt;\n      &lt;p&gt;World&lt;\/p&gt;\n    &lt;\/div&gt;\n  &lt;\/div&gt;\n&lt;\/body&gt;\n&lt;\/html&gt;\n<\/code><\/pre>\n<p>Now, how about we spruce things up a little? Let me show you the React way of handling this:<\/p>\n<pre><code class=\"javascript\">var HelloModal = React.createClass({\n  getInitialState: function() {\n    return {\n      visible: false\n    };\n  },\n  componentDidMount: function() {\n    var self = this;\n    $(window).on('modal.visible', function(ev){\n      self.setState({visible: true});\n    });\n    $(window).on('modal.hidden', function(ev){\n      self.setState(self.getInitialState());\n    });\n  },\n  render: function() {\n    var modal_classes = (this.state.visible)? 'ui small modal transition visible active' : 'ui small modal transition hidden';\n    return (\n      &lt;div className={modal_classes}&gt;\n        &lt;div className=\"ui center aligned header\"&gt;Hello&lt;\/div&gt;\n        &lt;div className=\"content\"&gt;\n          &lt;p&gt;World&lt;\/p&gt;\n        &lt;\/div&gt;\n      &lt;\/div&gt;\n    );\n  }\n});\n\nvar ModalPage = React.createClass({\n  getInitialState: function() {\n    return {\n      visible: false\n    };\n  },\n  componentDidMount: function() {\n    var self = this;\n    $(window).on('modal.visible', function(ev){\n      self.setState({visible: true});\n    });\n    $(window).on('modal.hidden', function(ev){\n      self.setState(self.getInitialState());\n    });\n  },\n  handleClick: function(ev){\n    if (ev.target == this.getDOMNode()){\n      $(window).trigger('modal.hidden');\n    }\n  },\n  render: function() {\n    var modal_classes = (this.state.visible)? 'ui dimmer modals page transition visible active' : 'ui dimmer modals page transition hidden';\n    return (\n      &lt;div className={modal_classes} onClick={this.handleClick}&gt;\n        &lt;HelloModal \/&gt;\n      &lt;\/div&gt;\n    );\n  }\n});\n\nvar showModal = function(){\n  $(window).trigger('modal.visible');\n}\n\n$(function(){\n  React.render(\n    &lt;div&gt;\n      &lt;div className=\"ui teal button\" onClick={showModal}&gt;Show Modal&lt;\/div&gt;\n      &lt;ModalPage \/&gt;\n    &lt;\/div&gt;,\n    document.getElementById('app')\n  );\n});<\/code><\/pre>\n<p>Ok, that might seem like a bit much, but you&#8217;ve got to remember React is not meant for prototyping hello world apps, what might seem like overkill for a single modal, becomes extremely useful when handling thousands of them in real-time across multiple instances of the app.<\/p>\n<p>In any case, here&#8217;s the brake-down; our React app has two components:<\/p>\n<p>The modal, which is basically a copy and paste within a React class of the good ol&#8217; HTML we had before.<\/p>\n<pre><code class=\"javascript\">var HelloModal = React.createClass({\n  \/\/ ...\n  render: function() {\n    var modal_classes = (this.state.visible)? 'ui small modal transition visible active' : 'ui small modal transition hidden';\n    return (\n      &lt;div className={modal_classes}&gt;\n        &lt;div className=\"ui center aligned header\"&gt;Hello&lt;\/div&gt;\n        &lt;div className=\"content\"&gt;\n          &lt;p&gt;World&lt;\/p&gt;\n        &lt;\/div&gt;\n      &lt;\/div&gt;\n    );\n  }\n});<\/code><\/pre>\n<p>And the modal container; this one would generally be created by Semantic UI when calling <code>$(x).modal();<\/code>, and again, React owns the DOM, so:<\/p>\n<pre><code class=\"javascript\">var ModalPage = React.createClass({\n  \/\/ ...\n  render: function() {\n    var modal_classes = (this.state.visible)? 'ui dimmer modals page transition visible active' : 'ui dimmer modals page transition hidden';\n    return (\n      &lt;div className={modal_classes} onClick={this.handleClick}&gt;\n        &lt;HelloModal \/&gt;\n      &lt;\/div&gt;\n    );\n  }\n});<\/code><\/pre>\n<p>In both cases the <code>modal_classes<\/code> variable will be how we&#8217;ll control the modal showing and hiding (in semantic CSS classes the <code>transition visible active<\/code> and <code>transition visible hidden<\/code> respectively).<\/p>\n<p>To manage the communication between React components effectively we can leverage Semantic&#8217;s dependency on jQuery, using jQuery to dispatch events to update their states.<\/p>\n<p>Both for the modal and the modal container we make sure to initialize their respective states so that it tracks the visibility of the component:<\/p>\n<pre><code class=\"javascript\">  \/\/ ...\n  getInitialState: function() {\n    return {\n      visible: false\n    };\n  },\n  \/\/ ...<\/code><\/pre>\n<p>Then, once the component has been mounted we attach the event listener which will show and hide it:<\/p>\n<pre><code class=\"javascript\">  \/\/ ...\n  componentDidMount: function() {\n    var self = this;\n    $(window).on('modal.visible', function(ev){\n      self.setState({visible: true});\n    });\n    $(window).on('modal.hidden', function(ev){\n      self.setState(self.getInitialState());\n    });\n  },\n  \/\/ ...<\/code><\/pre>\n<p>On the modal container we can manage the hiding of it all when clicked by generating a click handler:<\/p>\n<pre><code class=\"javascript\"> \/\/ ...\n  handleClick: function(ev){\n    if (ev.target == this.getDOMNode()){\n      $(window).trigger('modal.hidden');\n    }\n  },\n  \/\/ ...<\/code><\/pre>\n<p>and then attaching it:<\/p>\n<pre><code class=\"javascript\">  \/\/ ...\n  &lt;div className={modal_classes} onClick={this.handleClick}&gt;\n  \/\/ ...<\/code><\/pre>\n<p>And that&#8217;s it!<\/p>\n<p>The HTML needs to load our JSX and wil become just a scaffold which ends up looking like this:<\/p>\n<pre><code class=\"javascript\">&lt;!doctype html&gt;\n&lt;html lang=\"en\"&gt;\n&lt;head&gt;\n  &lt;meta charset=\"UTF-8\"&gt;\n  &lt;title&gt;React Modal&lt;\/title&gt;\n  &lt;link rel=\"stylesheet\" href=\"semantic.min.css\"&gt;\n  &lt;script src=\"jquery.min.js\"&gt;&lt;\/script&gt;\n  &lt;script src=\"semantic.min.js\"&gt;&lt;\/script&gt;\n  &lt;script src=\"babel-core.browser.js\"&gt;&lt;\/script&gt;\n  &lt;script src=\"react.js\"&gt;&lt;\/script&gt;\n  &lt;script type=\"text\/babel\" src=\"ReactApp.jsx\"&gt;&lt;\/script&gt;\n&lt;\/head&gt;\n&lt;body&gt;\n  &lt;div id=\"app\"&gt;\n    &lt;!-- template content goes here --&gt;\n  &lt;\/div&gt;\n&lt;\/body&gt;\n&lt;\/html&gt;<\/code><\/pre>\n<p>As you can see, from the script dependencies, we can use babel toautomagically transform JSX to runnable code simply by setting the <code>type<\/code> of the <code>.jsx<\/code> file to <code>text\/babel<\/code>.<\/p>\n<p>Here&#8217;s a Gist I uploaded with working code for you to try out:<\/p>\n<p><a href=\"https:\/\/gist.github.com\/jeanlescure\/b50d2393036f4dbdc183\" target=\"_blank\" rel=\"noopener noreferrer\">https:\/\/gist.github.com\/jeanlescure\/b50d2393036f4dbdc183<\/a><\/p>\n<p>And here&#8217;s a comparison between the old HTML and the React.js version:<\/p>\n<p>As I mentioned earlier, animations on Semantic UI are also handled on CSS, but, I&#8217;ve noticed that the way it does it is by adding animation CSS classes to it&#8217;s animated modules and then removing them after completion. So maybe a React animation shim for Semantic might be needed.<\/p>\n<p>In any case, for all intents and pruposes, React and Semantic play along way better than I could&#8217;ve anticipated, so expect a follow-up article with an actual working app.<\/p>\n<p>Happy Coding!<\/p>","protected":false},"excerpt":{"rendered":"<p>I&#8217;ve been playing around for a while with Facebook&#8217;s answer to multi-platform real-time apps, React.js and React Native. I can say I&#8217;m thoroughly convinced million-user architectures will default to React, JSX, and a flavor of Web Sockets or WebRTC for handling real-time. Today I&#8217;m going to share with you a nice surprise I got when [&hellip;]<\/p>","protected":false},"author":11,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_et_pb_use_builder":"","_et_pb_old_content":"","_et_gb_content_width":""},"categories":[116],"tags":[149,150],"jetpack_featured_media_url":"","yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v15.7 - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<title>Using React.js and Semantic UI to Create Stylish Apps - AgilityFeat Panama Software Test Center<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/agilityfeatpanama.com\/en\/blog\/2015\/09\/using-react-js-and-semantic-ui-to-create-stylish-apps\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Using React.js and Semantic UI to Create Stylish Apps - AgilityFeat Panama Software Test Center\" \/>\n<meta property=\"og:description\" content=\"I&#8217;ve been playing around for a while with Facebook&#8217;s answer to multi-platform real-time apps, React.js and React Native. I can say I&#8217;m thoroughly convinced million-user architectures will default to React, JSX, and a flavor of Web Sockets or WebRTC for handling real-time. Today I&#8217;m going to share with you a nice surprise I got when [&hellip;]\" \/>\n<meta property=\"og:url\" content=\"https:\/\/agilityfeatpanama.com\/en\/blog\/2015\/09\/using-react-js-and-semantic-ui-to-create-stylish-apps\/\" \/>\n<meta property=\"og:site_name\" content=\"AgilityFeat Panama Software Test Center\" \/>\n<meta property=\"article:published_time\" content=\"2015-09-22T10:05:08+00:00\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Est. reading time\">\n\t<meta name=\"twitter:data1\" content=\"7 minutes\">\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"WebSite\",\"@id\":\"https:\/\/34.200.113.64\/#website\",\"url\":\"https:\/\/34.200.113.64\/\",\"name\":\"AgilityFeat Panama Software Test Center\",\"description\":\"AgilityFeat Panama offers customized, multilevel web and mobile software testing for a variety of industries.\",\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":\"https:\/\/34.200.113.64\/?s={search_term_string}\",\"query-input\":\"required name=search_term_string\"}],\"inLanguage\":\"en-US\"},{\"@type\":\"WebPage\",\"@id\":\"http:\/\/agilityfeatpanama.com\/blog\/2015\/09\/using-react-js-and-semantic-ui-to-create-stylish-apps\/#webpage\",\"url\":\"http:\/\/agilityfeatpanama.com\/blog\/2015\/09\/using-react-js-and-semantic-ui-to-create-stylish-apps\/\",\"name\":\"Using React.js and Semantic UI to Create Stylish Apps - AgilityFeat Panama Software Test Center\",\"isPartOf\":{\"@id\":\"https:\/\/34.200.113.64\/#website\"},\"datePublished\":\"2015-09-22T10:05:08+00:00\",\"dateModified\":\"2015-09-22T10:05:08+00:00\",\"author\":{\"@id\":\"https:\/\/34.200.113.64\/#\/schema\/person\/c34873e9bee22a4aab19b8a0e800aad0\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"http:\/\/agilityfeatpanama.com\/blog\/2015\/09\/using-react-js-and-semantic-ui-to-create-stylish-apps\/\"]}]},{\"@type\":\"Person\",\"@id\":\"https:\/\/34.200.113.64\/#\/schema\/person\/c34873e9bee22a4aab19b8a0e800aad0\",\"name\":\"Jean\",\"image\":{\"@type\":\"ImageObject\",\"@id\":\"https:\/\/34.200.113.64\/#personlogo\",\"inLanguage\":\"en-US\",\"url\":\"https:\/\/secure.gravatar.com\/avatar\/?s=96&d=mm&r=g\",\"caption\":\"Jean\"}}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","_links":{"self":[{"href":"https:\/\/agilityfeatpanama.com\/en\/wp-json\/wp\/v2\/posts\/1171"}],"collection":[{"href":"https:\/\/agilityfeatpanama.com\/en\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/agilityfeatpanama.com\/en\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/agilityfeatpanama.com\/en\/wp-json\/wp\/v2\/users\/11"}],"replies":[{"embeddable":true,"href":"https:\/\/agilityfeatpanama.com\/en\/wp-json\/wp\/v2\/comments?post=1171"}],"version-history":[{"count":0,"href":"https:\/\/agilityfeatpanama.com\/en\/wp-json\/wp\/v2\/posts\/1171\/revisions"}],"wp:attachment":[{"href":"https:\/\/agilityfeatpanama.com\/en\/wp-json\/wp\/v2\/media?parent=1171"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/agilityfeatpanama.com\/en\/wp-json\/wp\/v2\/categories?post=1171"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/agilityfeatpanama.com\/en\/wp-json\/wp\/v2\/tags?post=1171"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}