<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Aki Rautio</title>
    <description>The latest articles on DEV Community by Aki Rautio (@akirautio).</description>
    <link>https://dev.to/akirautio</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F169657%2F778158a4-4bfb-4a54-a84d-6640fad15e06.jpg</url>
      <title>DEV Community: Aki Rautio</title>
      <link>https://dev.to/akirautio</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/akirautio"/>
    <language>en</language>
    <item>
      <title>Different ways of writing styles in React</title>
      <dc:creator>Aki Rautio</dc:creator>
      <pubDate>Sun, 31 Jul 2022 17:54:00 +0000</pubDate>
      <link>https://dev.to/akirautio/different-ways-of-writing-styles-in-react-1633</link>
      <guid>https://dev.to/akirautio/different-ways-of-writing-styles-in-react-1633</guid>
      <description>&lt;p&gt;Writing CSS styles is essential for frontend applications, but CSS doesn't scale well. The lack of namespaces or types makes writing styles for complex applications error-prone. Luckily multiple solutions resolve these issues and work well with React.&lt;/p&gt;

&lt;p&gt;All the solutions take a bit different approaches to make CSS easier to maintain and have a different set of features and drawbacks. Thus why selecting a suitable solution will enable you to write better code.&lt;/p&gt;

&lt;p&gt;Note: Many of these libraries work with other frontend frameworks too but this article focuses on libraries that work with React.&lt;/p&gt;

&lt;h1&gt;
  
  
  CSS files
&lt;/h1&gt;

&lt;p&gt;The classical way of writing styles for the React application is to write CSS files and use them with Javascript.&lt;/p&gt;

&lt;p&gt;The solutions that use CSS files are rarely limited to React since the concepts are universal and the connection between CSS and React is the class name.&lt;/p&gt;

&lt;h2&gt;
  
  
  CSS files / Inline CSS
&lt;/h2&gt;

&lt;p&gt;Writing plain CSS files or inline CSS for React doesn't differ much from writing them for HTML files. The greatest difference is that to use className property instead of class.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// File: styles.css

.mainClass {
  border: 1px solid blue;
}
.errorClass {
  border: 1px solid red;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// File: App.ts

import 'styles.css';

function App({ error }: AppProps){

  return (
    &amp;lt;div className={error ? "errorClass" : "mainClass"} style={{ color: 'red' }}&amp;gt;Main Activity&amp;lt;/div&amp;gt;
  )
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is a very barebone way to write CSS and it aligns strongly with the way CSS is used in a normal HTML page. Plain CSS enables an easy way to use the same styles between applications regardless of the framework and the CSS files are usable immediately.&lt;/p&gt;

&lt;p&gt;The downsides of using only CSS or inline CSS are the ones we mentioned earlier. Your React code doesn't know whether the particular class name exists and CSS is lacking namespacing so you can easily override the previous class. The whole process of providing CSS is also manual so there is no automated merging or splitting of CSS files.&lt;/p&gt;

&lt;p&gt;Using plain CSS files works well for reasonably small websites or applications where complexity doesn't get high and the styles are needed to be shared between different frameworks (or just with HTML). In React I would suggest using CSS files through CSS modules if the build system includes the feature.&lt;/p&gt;

&lt;h2&gt;
  
  
  SASS / LESS
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://sass-lang.com/"&gt;SASS&lt;/a&gt; and &lt;a href="https://lesscss.org/"&gt;LESS&lt;/a&gt; are preprocessors for CSS. They offer a programmatical approach to writing styles which will be turned into standard CSS.&lt;/p&gt;

&lt;p&gt;Using SASS and LESS works very much the same way as normal CSS and the difference only comes when bundling the code.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// File: styles.scss

$normal-border: blue;
$error-border: red;

.mainClass {
  border: 1px solid $normal-border;
}
.errorClass {
  border: 1px solid $error-border;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// File: App.ts

import 'styles.scss';

function App({ error }: AppProps){

  return (
    &amp;lt;div
      className={error ? "errorClass" : "mainClass"}
      style={{ color: 'red' }}
    &amp;gt;
      Main Activity
    &amp;lt;/div&amp;gt;
  )
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The advantage of using either of the preprocessor is that a lot of repetitive styles can be automated (see an example from &lt;a href="https://akirautio.com/blog/creating-a-common-component-library-with-css-and-sass-in-react"&gt;the common component post&lt;/a&gt;). Adding variables or creating iterative loops makes it easy to write more complex classes without writing repetitive content manually.&lt;/p&gt;

&lt;p&gt;Since the preprocessor resolves the issue of creating programmatical styles, it might cause even more issues since you can easily use class names in React that do not exist.&lt;/p&gt;

&lt;p&gt;I would use SCSS or LESS when there is a need to create programmatical styles (ie. having different class names or having a need to calculate values or colors for the classes). When using a preprocessor, one should someway to test out that the classes exist and work as expected.&lt;/p&gt;

&lt;h2&gt;
  
  
  CSS modules
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://github.com/css-modules/css-modules"&gt;CSS modules&lt;/a&gt; couple CSS styles more tightly to React and at the same time solves the namespace issue. When a CSS file is imported to React, it will create a namespace for the file.&lt;/p&gt;

&lt;p&gt;The import gives an ability to connect the created namespace with the original one by returning an object with original class names as a key.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// File: styles.css

.mainClass {
  border: 1px solid blue;
}
.errorClass {
  border: 1px solid red;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// File: App.ts

import styles from 'styles.css';

function App({ error }: AppProps){

  return (
    &amp;lt;div
      className={error ? styles.errorClass : styles.mainClass
      style={{ color: 'red' }}
    &amp;gt;
      Main Activity
    &amp;lt;/div&amp;gt;
  )
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Depending on the connection between React and CSS files allows safer use of class names and makes recognition of the missing classes one step easier than using just plain CSS files. It's also good to note that CSS modules work with any preprocessing library like SASS or LESS.&lt;/p&gt;

&lt;p&gt;There are no real drawbacks to using CSS modules as is but it inherits the downsides of writing plain CSS. It naturally lacks the type checks and build-time checks whether the class exists.&lt;/p&gt;

&lt;p&gt;Using CSS files with CSS modules protects against complexity which makes it a viable option to use with more complex Javascript applications.&lt;/p&gt;

&lt;h1&gt;
  
  
  CSS-in-JS
&lt;/h1&gt;

&lt;p&gt;CSS in JS libraries move styles to Javascript files instead of handling them in a separate CSS file. The advantage is to keep all the logic within Javascript instead of splitting the logic between JS and CSS.&lt;/p&gt;

&lt;h2&gt;
  
  
  Styled components / Emotion
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://styled-components.com/"&gt;Styled components&lt;/a&gt; are one of the first ones that introduced CSS-in-JS and have been one of the most popular ones to use. &lt;a href="https://emotion.sh/"&gt;Emotion&lt;/a&gt; is another popular choice.&lt;/p&gt;

&lt;p&gt;Both libraries use the styled function that takes an HTML tag and the styles through template literals and returns a React component that creates an HTML element with the generated class name and CSS styles linked to that generated class name.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// File: App.ts

import styled from 'styled-components';

const Content = styled('div')&amp;lt;{ error: boolean }&amp;gt;`
  border: 1px solid ${props =&amp;gt; error ? props.theme.errorBorderColor: props.theme.borderColor};
`

function App({ error }: AppProps){
  const theme = {
    mainBorderColor: 'blue',
    errorBorderColor: 'red
  }

  return (
    &amp;lt;ThemeProvider theme={theme}&amp;gt;
      &amp;lt;Content
        error={error}
        style={{ color: 'red' }}
      &amp;gt;
        Main Activity
      &amp;lt;/Content&amp;gt;
    &amp;lt;/ThemeProvider&amp;gt;
  )
}

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The biggest advantage of styled function (and CSS-in-JS in general) is automated naming of classes and handling of CSS files. Using styled functions also gives a lot of freedom to write your style-related logic the way you want (see &lt;a href="https://akirautio.com/blog/creating-a-common-component-library-with-css-in-js-styled-components-jss-emotion"&gt;Common component examples&lt;/a&gt;). The styles can be more dynamic and passing specific values to components is easier.&lt;/p&gt;

&lt;p&gt;The dynamic behavior of the styled function is also a drawback due complexity of creating static class names. This needs computing power on runtime which may end up leading to slowness. While styled components include server-side rendering, complex styles are still slower to create than static styles.&lt;/p&gt;

&lt;p&gt;Styled components and emotion work well with an application that has a lot style related business logic (colors depend on the logic) and it excels more with applications that need dynamic styling.&lt;/p&gt;

&lt;h2&gt;
  
  
  Vanilla Extract
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://vanilla-extract.style"&gt;Vanilla Extract&lt;/a&gt; brings CSS-in-JS more to the traditional side. The styles are defined in a typescript file but they are separated from the rest of the application logic. While it also supports passing dynamic content, it's done often by variants and there are no full dynamics. This results that Vanilla Extract can generate styles statically and enable zero runtime need.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// File: styles.css.ts

import { style } from '@vanilla-extract/css';

export const [themeClass, vars] = createTheme({
  color: {
    mainBorder: 'blue'
    errorBorder: 'red'
  },
});

const base = style({
  border: '1px solid'
});

export const mainClass = styleVariants({
  main: [base, { background: vars.color.mainBorder }],
  error: [base, { background: vars.color.errorBorder }],
});

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// File: App.ts

import { mainClass } from './styles.css.ts';

function App({ error }: AppProps){

  return (
    &amp;lt;div
      className="${mainClass[error ? 'error' : 'primary']}"
      style={{ color: 'red' }}
    &amp;gt;
      Main Activity
    &amp;lt;/div&amp;gt;
  )
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A big advantage of Vanilla Extract is the type safety that enables autocomplete in VSCode and ensures that CSS is always correct. and eases up selecting the correct option for a style parameter.&lt;/p&gt;

&lt;p&gt;Another key feature with Vanilla Extract is generating CSS during build time instead of runtime. This can be either upside or downside depending on how much dynamic styling is needed. Vanilla extract offers using variants so there are some possibilities but they are very limited compared to styled components.&lt;/p&gt;

&lt;p&gt;The key drawbacks come from being strictly build-time. The development flow feels a lot more similar to writing plain CSS files than writing CSS-in-JS which might some people. Vanilla Extract also restricts writing some dependent styles (for a good reason) which might cause issues in case the application needs these.&lt;/p&gt;

&lt;p&gt;Vanilla Extract works well in applications where the performance is important and styles are only used within React. If the codebase uses Typescript, it would make a lot of sense to use Vanilla Extract instead of CSS files with CSS modules.&lt;/p&gt;

&lt;h1&gt;
  
  
  Utility libraries like Tailwind CSS
&lt;/h1&gt;

&lt;p&gt;Utility libraries like &lt;a href="https://tailwindcss.com/"&gt;TailwindCSS&lt;/a&gt; reduce the number of CSS styles needed to be written having commonly used styles abstracted to class names and using those class names to define the style of the HTML element. This keeps the class name size small which helps to keep the CSS file small especially when combined with postprocessor which excludes nonexisting class names.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function App({ error }){
  return (
    &amp;lt;div
      className={["border-2","border-solid",error ? "border-red" : "border-blue].join(" ")}
      style={{ color: 'red' }}
    &amp;gt;
      Main Activity
    &amp;lt;/div&amp;gt;
  )
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;While this is often seen as a tool to do only rapid prototyping, in my experience they are also usable in a real product, especially when combined with custom styles. Utility styles enable to keep the styling inside Javascript files and still not combine CSS in JS.&lt;/p&gt;

&lt;p&gt;The downside of the utility libraries is the naming of the new abstraction layer. Since all styles will be written with the new naming, it takes some time to be efficient. The utility libraries also cover only the usual scenarios which might be limiting.&lt;/p&gt;

&lt;p&gt;Utility libraries are somewhat middle ground between CSS-in-JS and plain CSS so they fit well in applications where styles are not handling something very unusual. Application with forms or tables would be a great use case, collaborative drawing application most likely not.&lt;/p&gt;

</description>
      <category>react</category>
      <category>css</category>
      <category>javascript</category>
    </item>
    <item>
      <title>Take control of feature implementation with a refining stage</title>
      <dc:creator>Aki Rautio</dc:creator>
      <pubDate>Sun, 04 Jul 2021 17:13:30 +0000</pubDate>
      <link>https://dev.to/akirautio/take-control-of-feature-implementation-with-a-refining-stage-22oi</link>
      <guid>https://dev.to/akirautio/take-control-of-feature-implementation-with-a-refining-stage-22oi</guid>
      <description>&lt;p&gt;The most valuable features I've ever created were the ones that had a clear objective for their implementation, and the entire team had complete control over their tasks throughout the development process. A well-executed refining stage is a major factor in the rest of the process running smoothly.&lt;/p&gt;

&lt;p&gt;When a developer is skilled at refining stories, they're better able to scope features in a way that captures their value in a reasonable and well-estimated time. It's a difficult skill to acquire because the appropriate level of detail differs between features.&lt;/p&gt;

&lt;h1&gt;
  
  
  When refinement goes wrong
&lt;/h1&gt;

&lt;blockquote&gt;
&lt;p&gt;"Let's see what happens when we get there." &lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;I've heard this comment many times in my career as I've worked on technical refinement, and I've said it myself as well. While this is a perfectly appropriate method for performing some less complex tasks, it is a risky approach.&lt;/p&gt;

&lt;p&gt;Since this approach means many decisions must be made on the fly, high-level refinement for particularly complex tasks is bound to fail, resulting in poor results and bugs.&lt;/p&gt;

&lt;p&gt;Here's such a story from a few years ago. We were in the implementation phase of a feature that we'd promised to deliver within two weeks from the start. During a refinement phase, the feature didn't look too complex, but when I started to implement it, I saw that we'd had missed some complexity, and I needed to design the proper logic for it while coding.&lt;/p&gt;

&lt;p&gt;The logic took longer to complete than I had expected, but I was happy—I had built a scalable solution to the problem in a short amount of time. To make up for lost time, I had to accelerate the rest of my work so that I could complete the full feature on time. How did I manage that? Well, I cut corners. I neglected automated testing, just pushing through and hoping that everything would operate correctly when I was done.&lt;/p&gt;

&lt;p&gt;Well, I had overlooked several edge cases while developing the logic, so we had to go through two different feature testing cycles before we got it right, and we ended two weeks behind schedule. Inadequate refining was the root cause of all these cascading events.&lt;/p&gt;

&lt;h1&gt;
  
  
  Taking control of the tasks
&lt;/h1&gt;

&lt;p&gt;From the developer's perspective, successful refinement should provide clarity about what needs to be developed so that during the implementation, the focus is on the details instead of the big picture. In my experience, being able to focus on one single well-defined task at a time gives me the ability to pay attention to details like code readability.&lt;/p&gt;

&lt;p&gt;When a developer needs to clarify feature scope or requirements while writing their code, they need to shift their focus between a zoomed-in view of the details they're currently working on and the big picture overview. This is very taxing for the brain and it leads to a feeling of not being in control of one's own tasks. It's important to be able to determine where to focus during each part of the development process.&lt;/p&gt;

&lt;p&gt;A well-executed refinement process has a lot of underlying focus points, and it requires all the team members contribute their expertise to the process. Without proper cooperation, it's not possible to get the best results. In my experience, following these principles during the refinement process, and involving developers in this process from the start, will help your team members each retain control over their tasks during the implementation phase.&lt;/p&gt;

&lt;h2&gt;
  
  
  1. Correct features create customer value
&lt;/h2&gt;

&lt;p&gt;Capturing customer value is a key motivation for investing time and effort to develop a feature. If the same customer value can be captured better with another feature or a different approach, it may be worth altering the feature's requirements.&lt;/p&gt;

&lt;p&gt;Since every team member perceives things from their own unique point of view, developers should be the ones to challenge decisions from a technical standpoint. To make this happen, developers should be involved in the refinement process as early as possible.&lt;/p&gt;

&lt;p&gt;To be honest, this is one of the most difficult parts of the process for developers to master. It takes a lot of experience to see alternative technical possibilities and identify the pros and cons early on. It's much easier to note them retrospectively. But with practice, developers can provide a lot of added value early in the refinement process.&lt;/p&gt;

&lt;h2&gt;
  
  
  2. Reasonably sized features help with constant delivery
&lt;/h2&gt;

&lt;p&gt;The size of a feature has a major impact on how well it captures value and how smoothly the development process runs. In my experience, if the feature is too big, refinement either takes a long time or is done at a high enough level that it cannot be executed successfully.&lt;/p&gt;

&lt;p&gt;In general, a feature that takes up to a month to deliver by a single developer is able to capture value effectively. Development at the feature level therefore remains agile when features are small enough to be refined ahead of time.&lt;br&gt;
The challenge about sizing a feature is that the connection between size and content isn't linear. Small parts of the feature can take a significant portion of the time to deliver.&lt;/p&gt;

&lt;p&gt;I've faced this when developing an offer system for various types of products. Implementing the offer flow (input data to output data) takes around half the time, and configuring different products for it takes the other half. This means that delivering the first product is significantly more time-consuming than any following products.&lt;/p&gt;

&lt;p&gt;There are a variety of ways to divide up the initial time-consuming work, and developers are the best people to recommend them. For example, the first feature could include only what is absolutely necessary by hard coding values, omitting validations, or deferring error handling until later.&lt;/p&gt;

&lt;h2&gt;
  
  
  3. Align the team with feature scoping and acceptance criteria
&lt;/h2&gt;

&lt;p&gt;Scoping features and documenting the scope in acceptance criteria makes it easier for the entire team to understand the details of the expected delivery. The goal of this phase is to get everyone on the same page about what will be included and excluded from the feature, making it easier to decide whether to address any edge cases. The result for good acceptance criteria is a better focus on the correct details for the implementation and testing phase.&lt;/p&gt;

&lt;p&gt;For example, in the previous offer system example, scoping would be crucial to ensure that we deliver only the parts that are needed for each product to work. Defining borders gives the developer a better understanding of where to focus on each step.&lt;/p&gt;

&lt;p&gt;Scoping should be done collaboratively within the team, because each team member has expertise to offer about what is feasible to scope in and out. If developers haven't yet completely invested themselves in the feature, this is the step where all unknowns should be addressed.&lt;/p&gt;

&lt;p&gt;Acceptance criteria are a method of documenting the feature scope by specifying the key requirements that must be completed before a feature is ready. These serve as a contract between team members to ensure that everyone is on the same page about the feature.&lt;/p&gt;

&lt;h2&gt;
  
  
  4. Split the feature into tasks that solve a single problem
&lt;/h2&gt;

&lt;p&gt;Once we have a well-defined feature with strong acceptance criteria, we can divide it into smaller tasks that allow developers to work on a single problem at a time and enable parallel execution between developers.&lt;/p&gt;

&lt;p&gt;In my experience, the more problems I try to handle at once, the more likely I am to make mistakes. Focusing on a single problem at a time improves the quality of my code. In our offer system example, a single task may be number formatter functionality. Separating this from other tasks would allow us to focus more on functionality outside of the happy path and specific use cases.&lt;/p&gt;

&lt;p&gt;Splitting is more than just having a list of tasks to complete. Since the feature we're building is rarely identical to one we've built previously, there are also unanswered questions about how best to execute each part of it. Organizing new problems into individual tasks clarifies what needs to be done and allows us to plan for each problem.&lt;/p&gt;

&lt;p&gt;A few years back, I had a feature that involved complicated form validation. Splitting the complex issues into separate tasks provided a specific problem to address, which I was able to work out with a small proof of concept during the refining stage. The implementation process became much more comfortable, because I already knew how things should be done and I could focus on details like how to make tests scalable.&lt;/p&gt;

&lt;h1&gt;
  
  
  Control leads to better code
&lt;/h1&gt;

&lt;p&gt;There is a clear contrast between a good refinement process and a fast one. When tasks focus on a single problem at a time, and developers have a firm idea of how to address each problem, the implementation phase is completed in the developer's hands.&lt;/p&gt;

&lt;p&gt;This also changes how developers are able to enjoy their work. Instead of finding their satisfaction in resolving ad-hoc challenges during implementation, when refinement is done correctly, developers feel good about being in control of the work and being able to focus on the specifics in each step. This may not create the same bursts of happiness that solving an unexpected problem does, but it does result in a more stable, positive environment during the whole development process.&lt;/p&gt;

</description>
      <category>productivity</category>
    </item>
    <item>
      <title>Being a good developer isn't all about the code</title>
      <dc:creator>Aki Rautio</dc:creator>
      <pubDate>Sun, 14 Mar 2021 21:25:04 +0000</pubDate>
      <link>https://dev.to/akirautio/being-a-good-developer-isn-t-all-about-the-code-4f6g</link>
      <guid>https://dev.to/akirautio/being-a-good-developer-isn-t-all-about-the-code-4f6g</guid>
      <description>&lt;p&gt;Software development isn't just writing good code. It's also about whether the right features are being delivered at the right time.&lt;/p&gt;

&lt;p&gt;This also means that the best developer is not the one who can write the best code. Instead, it's a combination of various abilities that allows the team to produce the right functionality at the right time.&lt;/p&gt;

&lt;h1&gt;
  
  
  Software development is a process
&lt;/h1&gt;

&lt;p&gt;The code is newer written in isolation. It's one step in a development process delivering new features (or fixing issues). The process depends on the organization and type of project but the following three steps are always present:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;A feature refinement&lt;/li&gt;
&lt;li&gt;Development&lt;/li&gt;
&lt;li&gt;Maintenance&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The features have to be defined before any code can be written. After the feature has been developed, it needs to be delivered and maintained.&lt;br&gt;
While the developer's focus is on the development step, a good developer doesn't just know how to write a good code, but he also acknowledges the other steps.In my experience, this also means that a good developer does not necessarily need to be an outstanding programmer.&lt;/p&gt;

&lt;p&gt;The specific skills depend on the specific position, the team and the stakeholders. For example, the ability to grasp business logic and suggest alternatives allows the developer to optimize the development towards greater value within the product team. In the best case, the same benefit can be accomplished without any code, which also reduces maintenance.&lt;/p&gt;

&lt;h1&gt;
  
  
  Process steps
&lt;/h1&gt;

&lt;p&gt;Splitting the development process into smaller parts helps to better understand what happens when the new features are being developed. The steps we use in this article are not the only way to separate the process, and they have been chosen because they help to demonstrate the useful skills.&lt;/p&gt;

&lt;p&gt;The software development process I introduced earlier is for a single feature, but the same thing can be applied to a high level as the same cycle is repeated in each feature.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fakirautio.com%2Fassets%2Fblog%2Fbetter-developer%2Fprocess-chart.svg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fakirautio.com%2Fassets%2Fblog%2Fbetter-developer%2Fprocess-chart.svg" alt="Development process"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If software development is applied to a large project, we will need a technical development step to ensure that our process does not slow down due to the amount of technical debt that we have in our project.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fakirautio.com%2Fassets%2Fblog%2Fbetter-developer%2Fsteps.svg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fakirautio.com%2Fassets%2Fblog%2Fbetter-developer%2Fsteps.svg" alt="Development process"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In following four chapters I'm introducing the main areas how the good developer can bring value on high level. Each of these points will get their own in-depth articles later on.&lt;/p&gt;

&lt;h2&gt;
  
  
  1. Feature refinement
&lt;/h2&gt;

&lt;p&gt;The aim of the feature refinement is to identify the required changes/additions to the current application and to break the feature into smaller pieces in order to be able to test and release it incrementally. Although responsibility for this process rests with a person who understands the needs of the customer, the best outcome is when the whole team is involved as soon as possible.&lt;/p&gt;

&lt;p&gt;As a developer, I have seen two key areas to influence the result of refinements; &lt;strong&gt;affecting how the features are build&lt;/strong&gt; and &lt;strong&gt;how long they take to develop&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Being part of the feature refinement, a good developer can influence the result of the feature to be technically more feasible and it brings the value that is defined for the feature. For example instead of developing a multistep form to request information from the user, maybe the information is available already somewhere and it can be automatically fetched.&lt;/p&gt;

&lt;p&gt;Estimation is another important aspect of refinement, since it helps to understand how long those features will take to get to the customer. The developer has a key role to play here, as the better the prediction is made, the easier it is to set expectations for the user. Therefore a good developer should have the ability to provide a high-level estimate of how long tasks take and the ability to communicate and cope with the uncertainties of the tasks.&lt;/p&gt;

&lt;p&gt;At the end of the estimation process, it should be reasonably clear how long the development of the feature will take and what needs to be done.&lt;/p&gt;

&lt;h2&gt;
  
  
  2. Development
&lt;/h2&gt;

&lt;p&gt;The creation step is not just the writing of a code. It's also about having a common view about development in a team and sharing the knowledge while creating new features. This can be only done if the code and patterns are understandable to everyone and it's done with good programming practices. Therefore I'd like to raise two primary areas; high-quality discussions about development within the team and a tested and clean code.&lt;/p&gt;

&lt;p&gt;There are plenty of ways to achieve a good conversation atmosphere inside the team and many more ways to get these conversations going at the right time. Ultimately, it comes to the willingness of individuals to interact and negotiate with each other. Having these skills is one of the most significant attributes of a good developer. Everyone does these things a little differently, but the most important part is to know your strengths and weaknesses and to find a way to improve these skills.&lt;/p&gt;

&lt;p&gt;Based on my experience, one of the early signs of a good developer is that their code is written in a testable manner and that proper unit and integration tests are carried out as part of the creation of the feature. This does not necessarily mean that the code coverage is 100%, but to ensure that critical factors have been tested and that uses cases of the code are documented.&lt;/p&gt;

&lt;h2&gt;
  
  
  3. Maintenance
&lt;/h2&gt;

&lt;p&gt;Maintenance in this context means all those activities that happen when the code goes to production and works as intended. While there are a lot of project related areas to take into account, every project has following two:&lt;/p&gt;

&lt;p&gt;The first is the release process and the infrastructure. A good developer has at least an understanding of the release process since it helps to ensure that changes in the code do not break the release.&lt;/p&gt;

&lt;p&gt;Error management is another key area. Even the best code doesn't always work as planned, so it's important to be able to recognize the cause of the problem. As a good developer, you can bring value by understanding how to set up a proper logging system and how to use it to debug problems or bottlenecks.&lt;/p&gt;

&lt;h2&gt;
  
  
  4. Technical development
&lt;/h2&gt;

&lt;p&gt;Not every feature has direct benefits for the user. Technical debt might get too big to keep the feature development fast enough or the new features need significant changes original setup. To my experience, a good developer can both justify these changes to the team so they get prioritized accordingly and a good developer can see when those changes are needed ahead of time so they don't come as a surprise.&lt;/p&gt;

&lt;h1&gt;
  
  
  Further reading
&lt;/h1&gt;

&lt;p&gt;In this article, we've just scratched the surface of these topics, so in the future, I'm going to concentrate on every single issue.&lt;br&gt;
Although many of these reflections have deviated from personal experience, my journey has been inspired a lot by Robert Martin's book &lt;a href="https://www.oreilly.com/library/view/clean-agile-back/9780135782002/" rel="noopener noreferrer"&gt;Clean Agile&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;If you have any comments or questions, I would gladly hear them.&lt;/p&gt;

</description>
      <category>career</category>
      <category>technology</category>
    </item>
    <item>
      <title>Reflections on developing Android application as a web developer</title>
      <dc:creator>Aki Rautio</dc:creator>
      <pubDate>Sat, 09 Jan 2021 11:40:21 +0000</pubDate>
      <link>https://dev.to/akirautio/reflections-on-developing-android-application-as-a-web-developer-p86</link>
      <guid>https://dev.to/akirautio/reflections-on-developing-android-application-as-a-web-developer-p86</guid>
      <description>&lt;p&gt;For a long while, I have had an idea for an android application. There is a garage in my housing complex that opens up by calling a specific mobile number. Often my mobile isn't close by when I would need to open the gate, so I thought of creating an app to solve this issue.&lt;/p&gt;

&lt;p&gt;Starting to develop for a new platform is relatively time-consuming compared to results, so the project has been stagnating for a while. When I stumbled on the new &lt;a href="https://developer.android.com/jetpack/compose"&gt;Jetpack Compose toolkit&lt;/a&gt; for the UI creation, my interest got up again since the project would also give insights into where the android development is going.&lt;/p&gt;

&lt;p&gt;Most of my software development experience comes from technologies, frameworks, and libraries used to build user interfaces for web applications so building a mobile application isn't too far from what I have used. Having specific tools and framework features to a specific platform are still something I haven't used to so here are my findings.&lt;/p&gt;

&lt;h2&gt;
  
  
  First setup
&lt;/h2&gt;

&lt;p&gt;Compared to web development, one of the significant differences is to have a proper IDE (Android Studio). IDE tackles almost all aspects of software development from the code versioning to create, evaluate, and debug the application. It also standardizes the underlying tools and hides them very well. For instance, as long as it works, you don't have to know what kind of commands Gradle needs when building an app. Having more focus on code and the features than steps to get the application working reduces the time to get something tangible shown on a device.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Vflfjvuw--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://akirautio.com/assets/blog/reflections-on-developing-android-application-as-a-web-developer/AndroidStudio.png%3F1" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Vflfjvuw--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://akirautio.com/assets/blog/reflections-on-developing-android-application-as-a-web-developer/AndroidStudio.png%3F1" alt="Android Studio" width="880" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;With all the helpful tools IDE provides, it's really easy and simple to start doing the first project. Right now this applies to all but Jetpack Compose which is an alpha state and needs additional packages to the project. Fortunately, Google offers a pretty straightforward &lt;a href="https://developer.android.com/jetpack/compose/setup"&gt;guide&lt;/a&gt; on&lt;br&gt;
how to proceed, so it's not too much trouble&lt;/p&gt;

&lt;p&gt;In total, I think it took something like 1-2 hours from downloading Android Studio to get the first application run on a device with all needed libraries (including Jetpack Compose) ready to use. In my opinion, that isn't too much considering that the same process without IDE would probably take a full day. I was also pleased with all the features provided by IDE, such as the red line indicator from errors and a wide range of automated suggestions to make code more readable.&lt;/p&gt;
&lt;h2&gt;
  
  
  Writing Kotlin
&lt;/h2&gt;

&lt;p&gt;A new programming language, Kotlin, is a second key difference to my standard development workflow. The difference isn't too big, coming from Javascript and Typescript. Compared to Java Kotlin feels a lot more readable and easier to comprehend so development feels more satisfying.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--5HS_s7Vx--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://akirautio.com/assets/blog/reflections-on-developing-android-application-as-a-web-developer/Kotlin.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--5HS_s7Vx--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://akirautio.com/assets/blog/reflections-on-developing-android-application-as-a-web-developer/Kotlin.png" alt="Kotlin" width="880" height="879"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Model View ViewModel design pattern
&lt;/h2&gt;

&lt;p&gt;As part of writing an Android software, I got to write ViewModel classes which are part of the Model View ModelView design pattern. This seems to get a lot of popularity in user interface applications lately. SwiftUI on iOS is also using MVVM and VueJS and Angular both promote separation of data and view components with their implementation. MVVM doesn't too much differentiate.&lt;/p&gt;

&lt;p&gt;A summary for this pattern is about handing UI layer and data layer separate and connecting them by ViewModel. This wasn't anything too new different from what I'm used to but having supportive elements to implement this eases up the work.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--GZSr0a4d--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://akirautio.com/assets/blog/reflections-on-developing-android-application-as-a-web-developer/MVVM.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--GZSr0a4d--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://akirautio.com/assets/blog/reflections-on-developing-android-application-as-a-web-developer/MVVM.png" alt="Model View ViewModel" width="880" height="275"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I ended up splitting the data parts even further roughly based on &lt;a href="https://josipsalkovic.com/2019/12/15/android-clean-mvvm-architecture/"&gt;Josip Šalković's article&lt;/a&gt;. This was especially useful when using Room as a local database since database calls were handled separately from the real logic and ViewModel code ended up being a pretty high level.&lt;/p&gt;
&lt;h2&gt;
  
  
  Dependence injector
&lt;/h2&gt;

&lt;p&gt;Dependency injection as a term is rarely used on React even though the mechanism is more or less available in there too. The idea is that dependencies can be defined as input parameters instead of defining them inside the component to give the flexibility to change the dependencies when needed. In my view, the greatest advantage is the simplicity of writing the tests, as injected dependencies are much easier to mock than closely coupled dependencies.&lt;/p&gt;

&lt;p&gt;My choice was to use &lt;a href="https://developer.android.com/training/dependency-injection/hilt-android"&gt;Hilt&lt;/a&gt; as a dependency injector because that's what the android documentation recommends. The base setup is simple and easy but Hilt does so much automatically that it's hard to comprehend what's going on behind. This isn't a big issue until something isn't working exactly as expected.&lt;/p&gt;

&lt;p&gt;For example, I had a Repository class that didn't have dependencies so I thought of doing it as a normal class. All seemed to be good until I started to build the application and got some weird build errors. It took quite a while to figure out that the cause was missing an empty injection setup.&lt;/p&gt;

&lt;p&gt;Although I like the simplicity that Hilt provides, it will eventually trigger bugs that take a lot of time to identify since too much magic happens behind the scenes. It would be much more work to do this manually, so I will continue to use Hilt, even with obvious downsides.&lt;/p&gt;
&lt;h2&gt;
  
  
  Jetpack Compose
&lt;/h2&gt;

&lt;p&gt;One of the most familiar parts of the android developer surprisingly was UI development with Jetpack Compose. The idea is almost identical to React where each UI component is a function and the whole UI is composed of those smaller UI components. Android also has mutableStateIF function that handles the internal state. The IDE also has a visual preview from the components that have @Preview annotation and this feels very much like what Storybook has been.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@Composable
fun ListItem(
    title: String,
    subtitle: String
){
  val textState = remember { mutableStateOf(TextFieldValue()) }

    Column(){
        Text(text = title)
        Text(text = subtitle)
        TextField( value = textState.value, onChangeValue = { textState.value = it } )
    }
}

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This certainly is another UI pattern getting more popularity. Besides Jetpack Compose, SwiftUI has a very similar type of pattern to write the UI, and more or less all web frontend frameworks are using the same pattern nowadays. I have been using this in React for quite a while and it certainly gives a huge boost to development compared to other development patterns in frontend work.&lt;/p&gt;

&lt;p&gt;To be said Jetpack definitely isn't fully ready yet (hence the alpha state) and that certainly can be felt.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Sometimes the compiler decided to produce random errors that went away after the entire application was rebuilt. The visual preview also stopped working in the end though I think it was due to an old version of the Android Studio.&lt;/li&gt;
&lt;li&gt;There is also some limitation on component level and on my two-month journey to finish the application, the API got a huge amount of significant changes.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Nevertheless, I can already feel how this will make UI development a lot easier in Android and it will make a transition between platforms a lot easier since there is no need to learn new patterns.&lt;/p&gt;

&lt;h2&gt;
  
  
  Quirks of developing to Android
&lt;/h2&gt;

&lt;p&gt;Jetpack wasn't the only part where things weren't as planned:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Permissions are something that I'm not used to handling and finding the right flow took some time (+ it's still in progress)&lt;/li&gt;
&lt;li&gt;Not all features are well defined or give an understandable error message. For example in android 10 opening activity in the background just doesn't work. No error but it just doesn't open anything.s&lt;/li&gt;
&lt;li&gt;I tested the application with a few different android versions but testing the application with every major android version and hardware provider like Samsung would take a huge amount of time.&lt;/li&gt;
&lt;li&gt;Android Studio is automating so many things that many tasks feel like magic. It also gives a feeling that something will break at any minute.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Adding an application to Play Store
&lt;/h2&gt;

&lt;p&gt;Once I got the first version of the application ready, it was time to release it in the Google Play store and that was quite a journey. As a web developer the software tends to be released as is so once you have finished the development, it's ready to be deployed and marketing can start.&lt;/p&gt;

&lt;p&gt;With Play Store, App needs have good descriptions, screenshots, and the marketing material beforehand and there is quite a huge amount of mandatory content to fill out even before you can submit the app package. And once everything is ready, the application will be reviewed before it's available for the customers. This will make the whole update and bug fix process a whole lot different from web development because it will take hugely longer to get the bug fixed in an application.&lt;/p&gt;

&lt;h2&gt;
  
  
  Findings
&lt;/h2&gt;

&lt;p&gt;The most significant finding from this experience is that &lt;strong&gt;developing to different platforms isn't that much different anymore as it used to be&lt;/strong&gt;. The patterns to build UI and architecture the application starts to resemble each on both web and native android even though the tools themselves may offer different features. This should make developers' life easier since knowledge from one platform can be at least somewhat utilized to other platforms.&lt;/p&gt;

&lt;p&gt;I would also see that the patterns I used in an android application gave me a better ability to use them more on the web and especially with React that gives the freedom to experiment. For example, MVVM design pattern can be created by simply separating the data and view layer with a middle layer that ensures rerenders when data behind changes.&lt;/p&gt;

&lt;p&gt;While there were a lot of similarities between platforms, &lt;strong&gt;the distribution with the mobile application is vastly different from the web&lt;/strong&gt;. Having an application store in between the client and developer is a whole lot different experience than distributing the result straight to the user. This also brings with a bunch of new challenges to be solved like how to ensure that changes services are taken into account on multiple client versions or how to distribute bug fixes. &lt;a href="https://blog.pragmaticengineer.com/10-engineering-challenges-due-to-the-nature-of-mobile-applications/#2-mistakes-are-hard-to-revert"&gt;George Orosz's blog post&lt;/a&gt; touches on these topics very well so I highly suggest reading his views.&lt;/p&gt;

&lt;p&gt;While VSCode is a good text editor, I definitely will miss many more IDE level features from Android studio. One of these is the storybook-like component view next to the code. On the other hand, having used to getting strict autoformatting on save with Prettier was something I missed while writing the app.&lt;/p&gt;

&lt;p&gt;If you are interested to see the result from this journey, the CallGates app is available on &lt;a href="https://play.google.com/store/apps/details?id=com.akirautio.callgate"&gt;Google Play&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>kotlin</category>
      <category>android</category>
    </item>
    <item>
      <title>Decouple design from the logic with React hooks</title>
      <dc:creator>Aki Rautio</dc:creator>
      <pubDate>Wed, 14 Oct 2020 17:40:20 +0000</pubDate>
      <link>https://dev.to/akirautio/decouple-design-from-the-logic-with-react-hooks-6fd</link>
      <guid>https://dev.to/akirautio/decouple-design-from-the-logic-with-react-hooks-6fd</guid>
      <description>&lt;p&gt;Splitting the application logic and business logic has been long a good practice in frontend development since it eases up changing and testing each part independently. The same can be also with UX logic and design.&lt;/p&gt;

&lt;p&gt;The idea for this writing came when I was trying to find a proper library for the date picker component in React. &lt;strong&gt;Most of the packages are including both application logic and design in the same package which tends to lead to a hacky solution on the project side&lt;/strong&gt; if any customization is needed.&lt;/p&gt;

&lt;p&gt;This can be also seen in our projects where coupling the design and the logic tightly together makes any new features to increase the component size. &lt;strong&gt;This tends to lead to feature-rich but huge components that are hard to test&lt;/strong&gt; and ensure that all things work correctly.&lt;/p&gt;

&lt;h1&gt;
  
  
  Writing stateless components
&lt;/h1&gt;

&lt;p&gt;Decoupling the logic and design starts by creating stateless components which are implementing the parts of the required design.&lt;/p&gt;

&lt;p&gt;To make this practical, let's do a custom tab component with this logic. For the design part, we can have two components; &lt;strong&gt;TabItem&lt;/strong&gt; to show a single tab and &lt;strong&gt;TabContainer&lt;/strong&gt; to wrap around the tabs.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;
&lt;span class="kr"&gt;interface&lt;/span&gt; &lt;span class="nx"&gt;TabItemProps&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;onClick&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;String&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nx"&gt;isSelected&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;Boolean&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nx"&gt;children&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;String&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;TabItem&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="nx"&gt;onClick&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;isSelected&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;children&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;}:&lt;/span&gt; &lt;span class="nx"&gt;TabItemProps&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;  &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;button&lt;/span&gt; &lt;span class="nx"&gt;onClick&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;onClick&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;children&lt;/span&gt;&lt;span class="p"&gt;)}&lt;/span&gt; &lt;span class="nx"&gt;className&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;isSelected&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;selected&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;children&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/button&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="kr"&gt;interface&lt;/span&gt; &lt;span class="nx"&gt;TabContainerProps&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;children&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ReactNode&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;TabContainer&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;children&lt;/span&gt; &lt;span class="p"&gt;}:&lt;/span&gt; &lt;span class="nx"&gt;TabContainerProps&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;div&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;children&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/div&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When creating these stateless components, the focus should be on how to split the functionality into smaller independent containers. There are not too many rules regarding this, and a lot of different solutions work, so the most beneficial practice is to keep consistent.&lt;/p&gt;

&lt;p&gt;Even though the components are not including any state inside, they will hold some logic based on given properties so that they can execute required the user experience. Depending on your solution, the components can either hold the logic or just the states derived from the logic.&lt;/p&gt;

&lt;p&gt;For example, the TabItem has isSelected property that explicitly describes the use case. The same could be done by active property that is more generic and gives the logic part more power to decide when a single tab is active.&lt;/p&gt;

&lt;p&gt;Ensuring that stateless component looks exactly as they should, we should create tests for them. Since they don't hold internal logic, testing is a lot easier since we only need to ensure that each state works as expected. This can become by either using snapshot testing (from DOM or screenshot) with either local tools like &lt;a href="https://www.npmjs.com/package/@storybook/addon-storyshots"&gt;Storybooks storyshots&lt;/a&gt; or &lt;a href="https://www.chromatic.com/"&gt;Chromatic&lt;/a&gt;.&lt;/p&gt;

&lt;h1&gt;
  
  
  Adding hooks into stateless components
&lt;/h1&gt;

&lt;p&gt;To make those stateless components work together, we'll create a hook that handles all the required logic. It necessary doesn't need to contain the state but it should pass all the data and actions to components.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;
&lt;span class="kr"&gt;interface&lt;/span&gt; &lt;span class="nx"&gt;Tab&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;String&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;String&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;isSelected&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;Boolean&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;isDisabled&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;Boolean&lt;/span&gt;&lt;span class="p"&gt;?&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;


&lt;span class="kr"&gt;interface&lt;/span&gt; &lt;span class="nx"&gt;useTabHook&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;tabList&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Tab&lt;/span&gt;&lt;span class="p"&gt;[],&lt;/span&gt;
    &lt;span class="nx"&gt;onChangeTab&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;String&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt;
    &lt;span class="nx"&gt;content&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;selectedTab&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;String&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;any&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;useTabs&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;tabs&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Tab&lt;/span&gt;&lt;span class="p"&gt;[],&lt;/span&gt; &lt;span class="nx"&gt;content&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;any&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;useTabHook&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;  &lt;span class="p"&gt;{&lt;/span&gt;

    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;selectedTab&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setSelectedTab&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;useState&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;tabs&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]?.&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;tabList&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;tabs&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt;&lt;span class="err"&gt; &lt;/span&gt;&lt;span class="p"&gt;[]).&lt;/span&gt;&lt;span class="nx"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;item&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="nx"&gt;item&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;isSelected&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;selectedTab&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="nx"&gt;item&lt;/span&gt;&lt;span class="p"&gt;?.&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt; &lt;span class="p"&gt;})),&lt;/span&gt;
        &lt;span class="na"&gt;onChangeTab&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;setSelectedTab&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
        &lt;span class="na"&gt;content&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;content&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;selectedTab&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The scope of the hooks should mainly to cover the logic and exclude all style related variables (classnames or inline styles). Sometimes it may make sense to add accessibility or utility properties for the styles coming from the hook.&lt;/p&gt;

&lt;p&gt;The hooks should also consume all the external data and actions the component is needing even though some of the data goes straight to return values. Including all necessary properties to the hook makes the usage a lot easier since it's known where the data is coming, and there are no hidden requirements.&lt;/p&gt;

&lt;p&gt;Since the hook handles all the data transformation and action execution, a developer-friendly API and composable internal parts are the keys to success. They may not be very visible when the component is relatively simple, like in our example, but once complexity increases, making an effort to the API results a huge difference.&lt;/p&gt;

&lt;p&gt;Since we are only focusing on data transformation and actions, testing is more straight forward. There is no need to use DOM as an intermediate layer, but we can do all the purely to hooks input and out properties.&lt;br&gt;
There is also a library to ease up testing the hook called &lt;a href="https://github.com/testing-library/react-hooks-testing-library"&gt;react-hooks-testing-library&lt;/a&gt;.&lt;/p&gt;
&lt;h1&gt;
  
  
  Combine stateless components and the hook
&lt;/h1&gt;

&lt;p&gt;Lastly, we need to combine the logic to the design by creating a component that uses the stateless component in a manner the hook defines.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kr"&gt;interface&lt;/span&gt; &lt;span class="nx"&gt;TabsProps&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;tabs&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Tab&lt;/span&gt;&lt;span class="p"&gt;[];&lt;/span&gt;
  &lt;span class="nl"&gt;children&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ReactNode&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;Tabs&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;tabs&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;children&lt;/span&gt; &lt;span class="p"&gt;}:&lt;/span&gt; &lt;span class="nx"&gt;TabsProps&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;tabList&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;onChangeTab&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;content&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;useTabs&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;tabs&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;children&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;React&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Fragment&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;TabContainer&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;React&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Fragment&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
          &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;tabList&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(({&lt;/span&gt; &lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="nx"&gt;tab&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
            &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;TabItem&lt;/span&gt; &lt;span class="p"&gt;{...&lt;/span&gt;&lt;span class="nx"&gt;tab&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="nx"&gt;onClick&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;onChangeTab&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
              &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
            &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/TabItem&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;          &lt;span class="p"&gt;))}&lt;/span&gt;
        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/React.Fragment&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/TabContainer&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;      &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;children&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/React.Fragment&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;  &lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Both stateless components and the hook have been tested thoroughly so the main component only needs an integration level testing to check that both elements work properly together. In our example, the tests would ensure the Tabs component is rendered properly, and the key flows are working as expected.&lt;/p&gt;

&lt;h1&gt;
  
  
  Advantages and disadvantages of this practice
&lt;/h1&gt;

&lt;p&gt;Decoupling makes testing a lot easier since we can use the correct tools and practices for both design and logic. While logic testing is about checking outputs after certain actions, design testing is more of checking that DOM/rendered components. These need relatively different tools and testing practices so mixing them up due to coupling not only creates more tests but also creates unnecessary work for both test types.&lt;/p&gt;

&lt;p&gt;While testing something that can be handled with coupled components, the real advantage comes when there are new requirements for either design or logic that doesn't match with already made ones. For example, you may have multiple products that are using the same codebase and have slightly different requirements for the design or the logic.&lt;/p&gt;

&lt;p&gt;For example, in our case, if there are products with the same type of tab logic but different design, the hook part can be reused. And if one of the tabs needs a disabled that can be extended by composing a new hook with disabled logic around the current hook.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Additional TabItem component with disabled state&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;DisabledTabItem&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="nx"&gt;onClick&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nx"&gt;isSelected&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;isDisabled&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;children&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;value&lt;/span&gt;
&lt;span class="p"&gt;}):&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;onClick&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;MouseEvent&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;HTMLButtonElement&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nx"&gt;isSelected&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;Boolean&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;isDisabled&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;Boolean&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nx"&gt;children&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;String&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;String&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;button&lt;/span&gt; &lt;span class="nx"&gt;onClick&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;onClick&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="nx"&gt;disabled&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;isSelected&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;children&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/button&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;// Extented hook to handle disabled state&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;useDisabledTabs&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;input&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;content&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;useTabs&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;input&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="nx"&gt;content&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;onChange&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;tab&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;input&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;tabs&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;find&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;item&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;item&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;target&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nx"&gt;item&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;isDisabled&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;tab&lt;/span&gt; &lt;span class="o"&gt;!==&lt;/span&gt; &lt;span class="kc"&gt;undefined&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nx"&gt;content&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;onChange&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// Combining extra features&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;TabsWithDisable&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;tabs&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;children&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;tabList&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;onChangeTab&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;content&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;useDisabledTabs&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="nx"&gt;tabs&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;content&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;children&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;})&lt;/span&gt;

  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;React&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Fragment&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;TabContainer&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;tabList&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;forEach&lt;/span&gt;&lt;span class="p"&gt;(({&lt;/span&gt; &lt;span class="nx"&gt;text&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="nx"&gt;tab&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
          &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;DisabledTabItem&lt;/span&gt; &lt;span class="p"&gt;{...&lt;/span&gt;&lt;span class="nx"&gt;tab&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="nx"&gt;onClick&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;onChangeTab&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
            &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;text&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
          &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/DisabledTabItem&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;        &lt;span class="p"&gt;))}&lt;/span&gt;
      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/TabContainer&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;      &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;content&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/React.Fragment&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;  &lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In both the reusable parts are easy to take and only the new code needs to be tested again. This makes development a lot faster since there are no breaking changes towards already created components.&lt;/p&gt;

&lt;p&gt;Of course, these advantages don't come for free. Decoupling the logic and design also enables one to write code on top of the existing code that increases the level of dependencies. A high dependency tree will also lead to slow development if the base dependencies eventually need breaking changes. High dependency trees increase the difficulty to see the overall picture so there should be a balance between building on top and refactoring the current code.&lt;/p&gt;

&lt;h1&gt;
  
  
  Examples
&lt;/h1&gt;

&lt;p&gt;I have been happy to see that this practices has gotten more momentum lately and there are pretty good production ready packages to use.&lt;/p&gt;

&lt;h3&gt;
  
  
  Datepicker hooks
&lt;/h3&gt;

&lt;p&gt;First package I have been seen using this is &lt;a href="https://github.com/tresko/react-datepicker/tree/master/packages/hooks"&gt;@datepicker-react/hooks&lt;/a&gt;. There is also styled-components package for design but the hooks part can be used separately.&lt;/p&gt;

&lt;h3&gt;
  
  
  Adobe's React Spectrum
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://react-spectrum.adobe.com/"&gt;React Spectrum&lt;/a&gt; takes this even further by a hook library for both accessibility and logic for the most common use cases.&lt;/p&gt;

&lt;p&gt;If you know any more like this please write a comment! I would so much want know if there are more package like this.&lt;/p&gt;

&lt;h1&gt;
  
  
  Summary
&lt;/h1&gt;

&lt;p&gt;Decoupling design and logic can be done with a hook and stateless components. This enables creating new components based on the already written logic or design and test both logic and design separately.&lt;/p&gt;

</description>
      <category>react</category>
      <category>javascript</category>
      <category>design</category>
    </item>
    <item>
      <title>Document and test a common component library</title>
      <dc:creator>Aki Rautio</dc:creator>
      <pubDate>Fri, 24 Jul 2020 05:32:49 +0000</pubDate>
      <link>https://dev.to/akirautio/document-and-test-a-common-component-design-17oh</link>
      <guid>https://dev.to/akirautio/document-and-test-a-common-component-design-17oh</guid>
      <description>&lt;p&gt;Earlier in this series, we have gone through how to create your component library with different methods. Besides the tools to create the components themselves, documentation and testing create a lot of value to your library.&lt;/p&gt;

&lt;p&gt;Components in React consist of three ideas; understanding each state of the components, understanding the transitions between different states, and understanding the interaction in a component.&lt;/p&gt;

&lt;p&gt;For example, an Accordion component has two significant states, either one of the items is opened or we don't show any open items. Closing and opening the item can be animated which creates a transition between two states and interaction generally is done by clicking the header of the item.&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Far.kapsi.fi%2Fposts%2Fdocument-and-test%2FAccordion.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Far.kapsi.fi%2Fposts%2Fdocument-and-test%2FAccordion.gif" alt="Accordion"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Developing the following kind of a component can be done straight at the spot, but testing all states from the components can be a bit tricky in that specific spot especially if it connects with external data. Luckily there are a lot of isolated development tools that help to show all the states at once and even check whether there are any changes to all those states between commits. Combining these two features makes component development a lot more reliable and faster.&lt;/p&gt;

&lt;p&gt;One of these (and probably most popular) isolated development tools is Storybook. While there are other choices available (like &lt;a href="https://react-styleguidist.js.org/" rel="noopener noreferrer"&gt;Styleguidist&lt;/a&gt; and &lt;a href="https://reactcosmos.org/" rel="noopener noreferrer"&gt;React-Cosmos&lt;/a&gt;), &lt;a href="https://storybook.js.org/" rel="noopener noreferrer"&gt;Storybook&lt;/a&gt; combines both documentation in an isolated development environment and testing the changes between commit to the package which works pretty well and is relatively easy to set up.&lt;/p&gt;
&lt;h2&gt;
  
  
  Creating stories to cover all the states
&lt;/h2&gt;

&lt;p&gt;To speed up the development, you can create all the key states in Storybook and write your components based on them. In our Accordion example we defined, two states; one opened and all closed. Writing them in the storybook would look like this.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;react&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;Accordion&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;../src/Accordion/Accordion&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;title&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Accordion&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;AccordionClosed&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;First&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Second&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Third&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;item&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;index&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Accordion&lt;/span&gt; &lt;span class="nx"&gt;key&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;index&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="nx"&gt;index&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;index&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="nx"&gt;expanded&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;div&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;item&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/div&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/Accordion&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;  &lt;span class="p"&gt;))&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;AccordionSelectected&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;First&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Second&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Third&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;item&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;index&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Accordion&lt;/span&gt; &lt;span class="nx"&gt;key&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;index&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="nx"&gt;index&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;index&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="nx"&gt;expanded&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;div&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;item&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/div&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/Accordion&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;  &lt;span class="p"&gt;))&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nx"&gt;From&lt;/span&gt; &lt;span class="nx"&gt;https&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="c1"&gt;//github.com/ARautio/common-components-post/tree/master/packages/document-and-test&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Besides these two, we probably would like to try out the interaction to ensure that it works correctly and transitions look good. So we could also add the controlled version from the Accordion.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;AccordionControlled&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;selected&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setSelected&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;useState&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;First&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Second&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Third&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;item&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;index&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Accordion&lt;/span&gt;
      &lt;span class="nx"&gt;key&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;index&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
      &lt;span class="nx"&gt;index&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;index&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
      &lt;span class="nx"&gt;expanded&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;selected&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
      &lt;span class="nx"&gt;setExpanded&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;setSelected&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;div&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;item&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/div&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/Accordion&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;  &lt;span class="p"&gt;))&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;AccordionDynamic&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;AccordionControlled&lt;/span&gt; &lt;span class="o"&gt;/&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nx"&gt;From&lt;/span&gt; &lt;span class="nx"&gt;https&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="c1"&gt;//github.com/ARautio/common-components-post/tree/master/packages/document-and-test&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This all will create pages in Storybook which one can go back forth depending on which state is under development. For example, changing the color of the selected item would be easy to check out from this particular view.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Far.kapsi.fi%2Fposts%2Fdocument-and-test%2Fstorybook.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Far.kapsi.fi%2Fposts%2Fdocument-and-test%2Fstorybook.png" alt="Storybook in practice"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Storybook also offers better documentation and component property listing which brings the documentation even more available for everyone. In our example having the list of states and a dynamic component is enough since we are focusing on speeding the development and checking the states. If you would use this for documentation it would be good to add documentation of the properties and some text how the setup works.&lt;/p&gt;

&lt;h2&gt;
  
  
  Testing
&lt;/h2&gt;

&lt;p&gt;Testing in Storybook can be done a couple of ways, either by generating a text or image snapshot from React components (&lt;a href="https://www.npmjs.com/package/@storybook/addon-storyshots" rel="noopener noreferrer"&gt;Storyshots&lt;/a&gt;) with Jest and comparing it to the latest version. Both of these have their caveat points, but in general, they help to recognize unwanted changes.&lt;/p&gt;

&lt;p&gt;When using text snapshots with Storyshots, the test generates a snapfile from the story and compares it with the previous version to see if there are any changes. If you have added all possible states to the story, only transitions and integrations need to be tested out anymore. While snapfile makes it easy to see which components are changing, they generally don't provide a too good experience to understand what has been changed.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;exports[`Storyshots Accordion Accordion Down 1`] = `
Array [
  &amp;lt;div
    onClick={[Function]}
    style={
      Object {
        "backgroundColor": "blue",
        "cursor": "pointer",
        "margin": "2px",
        "padding": "12px",
      }
    }
  &amp;gt;
    &amp;lt;div&amp;gt;
      First
    &amp;lt;/div&amp;gt;
  &amp;lt;/div&amp;gt;,
  &amp;lt;div
    onClick={[Function]}
    style={
      Object {
        "backgroundColor": "blue",
        "cursor": "pointer",
        "margin": "2px",
        "padding": "12px",
      }
    }
  &amp;gt;
    &amp;lt;div&amp;gt;
      Second
    &amp;lt;/div&amp;gt;
  &amp;lt;/div&amp;gt;,
  &amp;lt;div
    onClick={[Function]}
    style={
      Object {
        "backgroundColor": "blue",
        "cursor": "pointer",
        "margin": "2px",
        "padding": "12px",
      }
    }
  &amp;gt;
    &amp;lt;div&amp;gt;
      Third
    &amp;lt;/div&amp;gt;
  &amp;lt;/div&amp;gt;,
]
`;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Image snapshot with &lt;a href="https://www.npmjs.com/package/@storybook/addon-storyshots-puppeteer" rel="noopener noreferrer"&gt;storyshots-puppeteer&lt;/a&gt; is one level higher from text snapshots because it compares generated images instead of the code. This gives a much easier way to see those differences but it also will give more false positives. Every time the code is generated to html page, there might be some 1px changes that trigger the change so the threshold needs to be defined properly. The positive side of the false positive is that they are relatively easy to check since test produces a visual diff.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Far.kapsi.fi%2Fposts%2Fdocument-and-test%2Fpuppeteer-test-js-puppeteer-storyshots-accordion-accordion-selected-diff.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Far.kapsi.fi%2Fposts%2Fdocument-and-test%2Fpuppeteer-test-js-puppeteer-storyshots-accordion-accordion-selected-diff.png" alt="Storybook image snapshot"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Covering all the key states of the components inside storybook and adding storyshots or storyshots-puppeteer to test those states, will ensure that you don't get surprised by changes. It also enables you to focus on testing the interactions and transitions between interactions with other methods (like Jest + react-testing-library) which saves your time.&lt;/p&gt;

&lt;p&gt;All this doesn't come without some costs because running all the tests will take significant time. In one of my applications, the total running time for roughly 1000 tests is around 4-5 minutes. It would be advisable if possible to run these tests within CI/CD so that they won't block you from writing the code.&lt;/p&gt;

&lt;p&gt;Another unfortunate challenge with snapshot testing is that they are done in isolation. This means that even though you had covered all the states of the component, it still may fail in your application because you didn't take into account it's surroundings. For example in one of my applications, the ID of the component overlapped with other components and showed the component differently than in Storybook.&lt;/p&gt;

&lt;p&gt;Both image testing and filenapshot testing also fail to show any issues with a specific browser because they are only focusing on either code or chrome. For multiple browser testing, there are extended tools like &lt;a href="https://www.chromatic.com/" rel="noopener noreferrer"&gt;Chromatic&lt;/a&gt; but they certain are not foolproof either.&lt;/p&gt;

&lt;h2&gt;
  
  
  Summary
&lt;/h2&gt;

&lt;p&gt;Documenting and testing React components in isolation eases up development because you are more aware of the changes that are happening to your components and you can faster check each key state of the component. Storybook is a compelling option for documentation and testing because it enables you to create all these states fast and has a possibility for automated tests without too much hassle. If your components are changing, the tests will notify you even when you wouldn't notice. This all though doesn't come without cost. Tests take a while to run and isolated development doesn't take into account it's surroundings. Unfortunately, the design testing only happens inside chrome but understanding the biggest effect usually is enough.&lt;/p&gt;

&lt;p&gt;If you want to check the code by yourself, the working demo is in &lt;a href="https://github.com/ARautio/common-components-post/tree/master/packages/document-and-test" rel="noopener noreferrer"&gt;my common components repository&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>storybook</category>
      <category>react</category>
      <category>testing</category>
    </item>
    <item>
      <title>Abstractions in React and how we are building forms</title>
      <dc:creator>Aki Rautio</dc:creator>
      <pubDate>Mon, 13 Jan 2020 06:29:50 +0000</pubDate>
      <link>https://dev.to/akirautio/abstractions-in-react-and-how-we-build-forms-50d8</link>
      <guid>https://dev.to/akirautio/abstractions-in-react-and-how-we-build-forms-50d8</guid>
      <description>&lt;h2&gt;
  
  
  Abstractions in general
&lt;/h2&gt;

&lt;p&gt;Abstraction is a result of a process to generalize the context and arrange and hide the complexity of the internals. The whole computer science is based on this idea and if you are a front-end developer, there are multiple layers of abstractions already under the code you are writing. Abstraction is a very powerful concept and it speeds up development hugely if done correctly.&lt;/p&gt;

&lt;p&gt;We see abstractions all around us and not just in software development. For example, automatic transmission in a car has two gears, R, D. These shifts abstract the necessary action to make the car either forward or backward so that the user can focus on driving. For example, if a user wants to make a car to go backward, the only two actions the user needs to think is putting the shift into R(everse) and pressing a gas pedal.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/http%3A%2F%2Far.kapsi.fi%2Fposts%2Fabstractions-in-js%2FAutomatic-transmission.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/http%3A%2F%2Far.kapsi.fi%2Fposts%2Fabstractions-in-js%2FAutomatic-transmission.png" alt="Automatic shift"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The same goes for programming where we continuously use abstraction. It begins at a very low level where the charge of the electrical current is converted into zeros and ones and goes all the way up to the ideas of the application you are developing. On a higher level, abstraction can be for example functions that standardize certain processes or classes which create structures for the data.&lt;/p&gt;

&lt;p&gt;In React abstractions are done by using &lt;a href="https://reactjs.org/docs/composition-vs-inheritance.html" rel="noopener noreferrer"&gt;composition&lt;/a&gt;. Higher-level components combine standardized lower-level components to be part of the user interface together. For example, a button could be part of the feedback form which can be part of the contact page. Each of the levels hides relevant logic inside the component and exposes necessary parts outside.&lt;/p&gt;

&lt;p&gt;For example, if we have a component that is responsible for an accordion, we can reuse the same component instead of re-writing it when we want an accordion to be part of the screen.  We may need to have a different design or a bit different functionality but as long as the accordion in a screen acts as accordion, we can reuse the base functionality.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/http%3A%2F%2Far.kapsi.fi%2Fposts%2Fabstractions-in-js%2FComposition-base.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/http%3A%2F%2Far.kapsi.fi%2Fposts%2Fabstractions-in-js%2FComposition-base.png" alt="Composition"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The key to success with the composition is to find the right abstraction layers for the project's components. Too many and too few layers of abstraction risk having redundant code and decelerating development speed. Too large abstraction layers mean that smaller common code components are repeated in each component. At the same time, too small abstractions repeat the usage of the components more than needed and having too many layers of code will slow the initial development.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/http%3A%2F%2Far.kapsi.fi%2Fposts%2Fabstractions-in-js%2FCompositionSmall-new.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/http%3A%2F%2Far.kapsi.fi%2Fposts%2Fabstractions-in-js%2FCompositionSmall-new.png" alt="Composition"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The proper levels of abstraction are hard to estimate before the significant parts of the application are ready and incorrect abstraction levels are the usual a cause for the need of refactoring later on. Defining the responsibilities of the components before development helps to reduce the amount of needed refactoring because it forces to justify the decisions. I can also suggest to create a bit too many abstraction layers than too few because layers are easier and cheaper to combine.&lt;/p&gt;

&lt;p&gt;In our accordion example, we first decided to expose the reveal and collapse functionality and color theme outside which means that accordion isn't any more responsible for that. This also means that we expect those two properties to differentiate a lot between the screen. Analyzing and determining the responsibilities for the components will help out see how components should be built the way that they are composable for your application. For me, this became obvious when in the latest project I have been involved.&lt;/p&gt;

&lt;h2&gt;
  
  
  Case: Forms in frontend of enterprise application
&lt;/h2&gt;

&lt;p&gt;Around a year ago we started to build an application to speed up one of the company's processes. As usual with all these kinds of business applications, the software would handle user inputs to fill the necessary data and then turn it to a product. I'll use this project to showcase how the abstraction worked for us. I'm going to focus on how we build forms since they were the key for this software and they ended up being the best example of an abstraction that I have done.&lt;/p&gt;

&lt;h2&gt;
  
  
  Starting a project
&lt;/h2&gt;

&lt;p&gt;Let's start with the starting point to get some understanding of the factors leading up to the decision we took. When the project began, the final state of the process was unknown like it usually is in agile development. Nonetheless, this allowed us to deal with a lot of uncertainty when defining abstracts, leading to much more careful analysis before the components were defined.&lt;/p&gt;

&lt;p&gt;In the context of forms, the base requirements were that we could have multiple of forms with different inputs. For me, this meant that we should make the form components extendable to as many situations as we could think while keeping the core as standard as possible.&lt;/p&gt;

&lt;h2&gt;
  
  
  How we abstracted forms
&lt;/h2&gt;

&lt;p&gt;Before we could start building the abstractions, we needed to understand the purpose of the forms. In our case, they are part of the process where a user can either create new data or alter the current data. While most of the data points are independent of each other, we still wanted to ensure that we can handle dependency either between the form fields or between a form field and a value from the server.&lt;/p&gt;

&lt;p&gt;The purpose of the fields is also to limit the given set of values. Data types are the general cause to limit the input. For example, when requesting a number input, we should limit users' ability to give something else. We also should be able to limit the input to a certain list of values by either limiting the input or validating the input.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/http%3A%2F%2Far.kapsi.fi%2Fposts%2Fabstractions-in-js%2FFormProcess.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/http%3A%2F%2Far.kapsi.fi%2Fposts%2Fabstractions-in-js%2FFormProcess.png" alt="Composition"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This process showed that we should have two abstractions; form and form field. Besides that, we noticed that we may have different types of fields if we want to limit the input in different ways.&lt;/p&gt;

&lt;h3&gt;
  
  
  Form
&lt;/h3&gt;

&lt;p&gt;Based on the previous process description we decided that the form in our case will be responsible for handling the state of the form data and validations. It should be also possible to give initial values and trigger the submit. The form shouldn't care where initial values come from or what happens on submit which means that these two should be exposed.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;Form&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;initialValues&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;onSubmit&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;children&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;children&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;&lt;span class="err"&gt; &lt;/span&gt;&lt;span class="p"&gt;...&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Field
&lt;/h3&gt;

&lt;p&gt;For the fields, we defined that we would need different types of limits for what the user can inputs. If there would be just a couple of different options it would make sense to include the logic inside the abstraction. For us, it was obvious from the beginning that we would have a lot of different types of data so we should expose the logic outside. And this wouldn't be only the logic but also UI part of each limit. For example, when we want user only to choose from the list, we should create a UI (ie. a drop-down) for that.&lt;/p&gt;

&lt;p&gt;All field elements also had some common elements like a label on the top or the side of the input and possible error or information message under the input. These we decided to include inside the abstraction since we expected these to be part of the all form fields.&lt;/p&gt;

&lt;p&gt;The result of these two decisions ended up creating two different abstractions. A field that is responsible for the data and surroundings of the input and an input type that is responsible to show the input field. Each of the different input types like TextInput would be their components which would all fill the same responsibility but a different way.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;Field&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;label&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;inputComponent&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Input&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;inputProps&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;value&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;undefined&lt;/span&gt; &lt;span class="cm"&gt;/*  Presents the value */&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;onChange&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;undefined&lt;/span&gt; &lt;span class="cm"&gt;/* Changes the value */&lt;/span&gt;
  &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;React&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Fragment&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;label&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Input&lt;/span&gt;
        &lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="nx"&gt;onChange&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;onChange&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="p"&gt;{...&lt;/span&gt;&lt;span class="nx"&gt;inputProps&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
      &lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/React.Fragment&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;  &lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// Text input in here is an example&lt;/span&gt;
&lt;span class="c1"&gt;// The props would be the same for all inputTypes&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;TextInput&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;({&lt;/span&gt;&lt;span class="err"&gt; &lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;(...)&lt;/span&gt;


&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;App&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Form&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Field&lt;/span&gt;
    &lt;span class="nx"&gt;label&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Test input&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
    &lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;TestElement&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
    &lt;span class="nx"&gt;inputComponent&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;TextInput&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/Form&amp;gt;   &lt;/span&gt;&lt;span class="err"&gt; 
&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Executing the abstraction
&lt;/h3&gt;

&lt;p&gt;After we got the abstractions and requirements for those abstractions ready, it was clear that our setup is universal so someone else should have solved the problem already. Using a ready-made package would ease our job because we wouldn't have to build everything from scratch. After some exploration, we ended up using &lt;a href="https://jaredpalmer.com/formik" rel="noopener noreferrer"&gt;Formik&lt;/a&gt; inside our abstraction.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/http%3A%2F%2Far.kapsi.fi%2Fposts%2Fabstractions-in-js%2FFormikInOurAbstraction.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/http%3A%2F%2Far.kapsi.fi%2Fposts%2Fabstractions-in-js%2FFormikInOurAbstraction.png" alt="Composition"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I would like to note that we are not exposing Formik to our application fully but only on Form and Field level. Formik is only filling the functionality of the abstraction, not creating it for us. This gives us an option to replace the package if we ever need something different in the future and we can also extend our abstraction beyond what Formik provides. The downside of this practice is that we need to write additional integration tests to ensure that Formik works along with our components as it should.&lt;/p&gt;

&lt;h3&gt;
  
  
  Creating input types
&lt;/h3&gt;

&lt;p&gt;The last piece from the form setup was the input types. Since on the Field level we exposed the input, we would need to have a separate component to fill the responsibility.&lt;/p&gt;

&lt;p&gt;It became very obvious while we had created some of these input types that besides data types (ie. text, number, date), the input type component depends on how we want to limit users' selection. For example text, input and group of radio items serve the same purpose but limit the selection very differently. We ended up having roughly 20 different input types in our application. The reason for so many components was that we wanted to abstract each input separately. For example text and number, input looks almost the same but they act differently. For the developer, it would be also easier to distinguish the inputs if they are different components.&lt;/p&gt;

&lt;p&gt;This didn't make us repeat a lot of code since the input components were composed of smaller components. I have liked very much the way atomic design splits components because it describes the abstraction layers reasonably well and helps to keep components composable.&lt;/p&gt;

&lt;p&gt;For inputs we created two abstraction layers:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Atoms - single functionality component like the design of the input field, functionality of a tooltip popup.&lt;/li&gt;
&lt;li&gt;Molecules - composes atoms to build higher-level items like in our case input type component.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;In our case, for example, the input component was reused between half of the input components because it was so generic. Probably the best example of having composable atoms in our case is Datepicker.&lt;/p&gt;

&lt;h3&gt;
  
  
  Datepicker example
&lt;/h3&gt;

&lt;p&gt;In the beginning, we used the browser way to handle dates but since we wanted to have the same looking field in all browsers, we decided to do our own. After exploring the available packages and we decided to use fantastic &lt;a href="https://github.com/tresko/react-datepicker" rel="noopener noreferrer"&gt;@datepicker-react/hooks&lt;/a&gt; hooks and create our design on top of that.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/http%3A%2F%2Far.kapsi.fi%2Fposts%2Fabstractions-in-js%2FCommonElementsDatepicker.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/http%3A%2F%2Far.kapsi.fi%2Fposts%2Fabstractions-in-js%2FCommonElementsDatepicker.png" alt="Composition"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Since we already had a lot of atoms developed, we only needed to create the calendar design which took something like 1.5 days to do from start till the end including tests. In my opinion, this demonstrates the power of the well-chosen abstraction layers which help to generalize the small component into composable atoms.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusions
&lt;/h2&gt;

&lt;p&gt;Generic abstract and composable components speed up development as each new feature also generates reusable components. Once we started developing the Datepicker, this became obvious to us. We've already had all the other components except the calendar itself.&lt;/p&gt;

&lt;p&gt;Defining responsibilities for the abstracted components eases up selecting the exposed and hidden logic inside the component. It makes the conversation more constructive within the team as we end up talking about architecture rather than implementation.  For example, we specified at the beginning that we expose the input component outside of our Field component. The strongest reasoning for this was that we may end up with a significant amount of different types of fields and we don't want to limit usage inside the field.&lt;/p&gt;

&lt;p&gt;Structuring the abstraction layers with some rules helps to declare the responsibilities and connection between abstraction layers. We used atomic design as a base for these rules. It defines five abstraction layers and gives them high-level responsibilities. This helps in the beginning to establish components which have the same abstraction level.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Thanks for reading this. If you have had same experience or have any comments or questions, I would gladly hear them.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>react</category>
      <category>abstraction</category>
      <category>frontend</category>
      <category>example</category>
    </item>
    <item>
      <title>Optional chaining with React</title>
      <dc:creator>Aki Rautio</dc:creator>
      <pubDate>Mon, 09 Dec 2019 05:39:34 +0000</pubDate>
      <link>https://dev.to/akirautio/optional-chaining-with-react-2l28</link>
      <guid>https://dev.to/akirautio/optional-chaining-with-react-2l28</guid>
      <description>&lt;p&gt;13.1.2020 UPDATE: &lt;a href="https://babeljs.io/blog/2020/01/11/7.8.0"&gt;Babel 7.8.0 supports optional chaining out of the box&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Optional Chaining is one of the most requested features in Javascript (and Typescript) which is no wonder since it solves a very fundamental problem; accessing the property from a dynamic deep object safely.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;
&lt;span class="c1"&gt;// A deep structure example &lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;deepObject&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; 
  &lt;span class="na"&gt;firstLevel&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; 
    &lt;span class="na"&gt;secondLevel&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; 
      &lt;span class="na"&gt;thirdLevel&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;value&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; 
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// Accessing thirdLevel safely without optional chaining&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;thirdLevelValue&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(((&lt;/span&gt;&lt;span class="nx"&gt;deepObject&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="p"&gt;{}).&lt;/span&gt;&lt;span class="nx"&gt;firstLevel&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="p"&gt;{}).&lt;/span&gt;&lt;span class="nx"&gt;secondLevel&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="p"&gt;{}).&lt;/span&gt;&lt;span class="nx"&gt;thirdLevel&lt;/span&gt;

&lt;span class="c1"&gt;// Accessing thirdLevel safely with optional chaining&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;thirdLevelValue&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;deepObject&lt;/span&gt;&lt;span class="p"&gt;?.&lt;/span&gt;&lt;span class="nx"&gt;firstLevel&lt;/span&gt;&lt;span class="p"&gt;?.&lt;/span&gt;&lt;span class="nx"&gt;secondLevel&lt;/span&gt;&lt;span class="p"&gt;?.&lt;/span&gt;&lt;span class="nx"&gt;thirdLevel&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The main advantage of using optional chaining is a smaller and cleaner code which makes it easier to comprehend once people get used to the syntax. &lt;/p&gt;

&lt;h1&gt;
  
  
  How to use optional chaining
&lt;/h1&gt;

&lt;p&gt;Last autumn &lt;a href="https://tc39.es/proposal-optional-chaining/"&gt;Optional Chaining&lt;/a&gt; proposal got to the Candidate stage (stage 3) which means that the specification is very close to the final version. This change resulted it to be part of Typescript 3.7 in late October 2019 and Create React App 3.3.0 at the beginning of December 2019. Also supporting tools like Prettier have already added the support.&lt;/p&gt;

&lt;p&gt;If you are using one of these, then optional chaining should work out of the box. At the current state (December 2019) the major editors like VSCode may need a bit of configuration to handle the new syntax but I would expect this to be changed very soon. If you have some trouble, check &lt;em&gt;Configuring VSCode to handle optional chaining&lt;/em&gt;-topic from below.&lt;/p&gt;

&lt;h2&gt;
  
  
  Using Optional chaining with Babel
&lt;/h2&gt;

&lt;p&gt;Typescript or CRA is luckily not the requirement to use optional chaining when developing with React. You can do the same with Babel &lt;strong&gt;7.8.0&lt;/strong&gt; and greater or with optional chaining plugin (&lt;a href="https://babeljs.io/docs/en/babel-plugin-proposal-optional-chaining"&gt;@babel/plugin-proposal-optional-chaining&lt;/a&gt;)&lt;/p&gt;

&lt;p&gt;Since babel usually isn't used alone but as part of the toolchain, the required packages may differ from setup to setup. If you are starting to use babel, I would suggest to first follow one of these tutorials / repos:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;a href="https://babeljs.io/en/setup"&gt;Babel setup&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://dev.to/0xhjohnson/setup-react-babel-7-and-webpack-4-2168"&gt;Babel with Webpack&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/ARautio/optional-chaining-post"&gt;Babel with ParcelJS&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;If you have older than 7.8.0, you need to install optional chaining plugin with following command:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;npm install --save-dev &lt;a class="mentioned-user" href="https://dev.to/babel"&gt;@babel&lt;/a&gt;/plugin-proposal-optional-chaining&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;and adding it to .babelrc&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="err"&gt;...&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"plugins"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"@babel/plugin-proposal-optional-chaining"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;

&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After this you should have a working setup.&lt;/p&gt;

&lt;h2&gt;
  
  
  Configuring VSCode to handle optional chaining
&lt;/h2&gt;

&lt;p&gt;As a default, VSCode uses typescript checking for Javascript React code and currently this isn't supporting optional chaining. There are ways to fix this: &lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Install &lt;a href="https://marketplace.visualstudio.com/items?itemName=ms-vscode.vscode-typescript-next"&gt;ms-vscode.vscode-typescript-next extension&lt;/a&gt; which adds support for new typescript features including optional chaining to &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Disabling &lt;a href="https://stackoverflow.com/a/42633555"&gt;typescript and javascript checking&lt;/a&gt; and installing and setting &lt;a href="https://marketplace.visualstudio.com/items?itemName=dbaeumer.vscode-eslint"&gt;Eslint extention&lt;/a&gt; to VSCode and configuring eslint to handle optional chaining.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Configuring Eslint to handle new syntax
&lt;/h2&gt;

&lt;p&gt;Eslint needs a &lt;em&gt;babel-eslint&lt;/em&gt; package to understand the new syntax.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;npm install --save-dev babel-eslint&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;It also needs addtional configuration to &lt;em&gt;.eslintrc&lt;/em&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"parser"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"babel-eslint"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="err"&gt;...&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;


&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  Advantages to use optional chaining compared to other options
&lt;/h1&gt;

&lt;p&gt;If you have been developing with Javascript (and especially with React) for some time, you may have used some functions to handle dynamic longer paths that shouldn't fail. It may have been either internally develop a solution or a function from the external package like &lt;a href="https://lodash.com/docs/#get"&gt;Get from Lodash&lt;/a&gt; or &lt;a href="https://ramdajs.com/docs/#path"&gt;Path from Ramda&lt;/a&gt;. &lt;/p&gt;

&lt;p&gt;All these functions are still as usable as they used to be but using a future native way in code makes it more future proof and reduces the amount of external code needed. Right now the optional chaining needs to be always transpiled but that won't be the case in the future. Once browsers and NodeJS start supporting it, the transpiling can be dropped without the need to change the code.&lt;/p&gt;

</description>
      <category>react</category>
      <category>optionalchaining</category>
      <category>javascript</category>
    </item>
    <item>
      <title>Creating a common component library with Component library (Material UI, BaseWeb, Chakra-UI)</title>
      <dc:creator>Aki Rautio</dc:creator>
      <pubDate>Tue, 03 Dec 2019 06:47:50 +0000</pubDate>
      <link>https://dev.to/akirautio/creating-a-common-component-library-with-component-library-material-ui-baseweb-chakra-ui-1lhb</link>
      <guid>https://dev.to/akirautio/creating-a-common-component-library-with-component-library-material-ui-baseweb-chakra-ui-1lhb</guid>
      <description>&lt;p&gt;Starting to create a common component library with a ready-made component library bring the most value in the beginning. These component libraries usually include some set of frequently used elements on the web and also give a chance for theming to speed up developing.&lt;/p&gt;

&lt;p&gt;There is a long history of ready-made component libraries that starts even before React. One of the most popular ones has been &lt;a href="https://getbootstrap.com/"&gt;Bootstrap&lt;/a&gt; for a very long time. Due to more complex design setups and better tools, a lot of ready-made component libraries for React have popping up in past years. Many of them are developed or at least initiated by big tech companies who also use them internally.&lt;/p&gt;

&lt;h1&gt;
  
  
  Reasoning to use component libraries
&lt;/h1&gt;

&lt;p&gt;The biggest advantage of using a ready-made component library is that a lot of components have been already developed and tested before the project even starts to develop. This gives a boost at the beginning of the project since no time spend on writing the basic components like buttons and typography elements. That time can be used for feature development instead.&lt;/p&gt;

&lt;p&gt;Most if not all ready-made component libraries also provide theming, so that design of the components can be aligned with the project in hand. &lt;/p&gt;

&lt;p&gt;Though there are two risks using a ready-made component library. Firstly the project will be very dependent on the library so any issues or limitations in components from library will take time to get sorted out. &lt;/p&gt;

&lt;p&gt;The ready-made component library also dictates pretty much which kind of tools should be used for developing the design. For example, Material UI uses the CSS-in-JS through their internal styled function. Using styled-components or pure CSS will cause issues and unnecessary complexity to the project.&lt;/p&gt;

&lt;h1&gt;
  
  
  Available ready made component libraries
&lt;/h1&gt;

&lt;p&gt;Probably one of the most known ready-made component library nowadays is Material UI which is based on Google material design. There are also tons of other options available, though many of them are still pretty young.&lt;/p&gt;

&lt;p&gt;I would start by looking following list first:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://material-ui.com/"&gt;Material UI&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://baseweb.design/"&gt;BaseWeb&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://elastic.github.io/eui/#/"&gt;Elastic UI&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://reakit.io/"&gt;Reakit&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://chakra-ui.com/"&gt;Chakra-UI&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;All mentioned packages are currently in active development so new features and fixes are coming constantly. While Material UI is the most popular one, all of them provide something unique.&lt;/p&gt;

&lt;p&gt;BaseWeb uses Styletron and makes override the base style while Elastic UI enables to use both scss and styled-component and offers a big variety of components. Reakit focuses on keeping a bundle size very small and ChakraUI has all components accessible.&lt;/p&gt;

&lt;h1&gt;
  
  
  How to select the one for me
&lt;/h1&gt;

&lt;p&gt;Since a component library will dictate a big part of the application, it's important to make a decision that fits to the project. Each project should use their parameters to define what fits but a good start would be to ensure that tools align, compatibility is enough for project needs and there are needed a component for the project.&lt;/p&gt;

&lt;p&gt;For the project, it would help a lot if the component library would use the same tools as the project itself (like styled-components) or that the tools the library uses, align with the idea what the project has. For example, BaseWeb uses styletron which is pretty close to styled-components but using styled-components and styletron in same project doesn't make sense.&lt;/p&gt;

&lt;p&gt;Another risk point is compatibility. Even a well made component library may cause a lot of issues if it's not aligned with other packages in projects. The biggest risks usually depend on the project but forms are usually the ones that cause issues. If component don't pass the actions or ref through, it may limit the usage of certain packages.&lt;/p&gt;

&lt;p&gt;Even a well build component library isn't usable if it's lacking many of the needed components in a project. Unfortunately packages group and name the components a bit differently so it takes quite some time to go through the list. It should also be taken into account that if a package has quite low-level (like popper and transition) components, there is less need to be fully fitting since those components should a lot easier to compose together from low level components.&lt;/p&gt;

&lt;h1&gt;
  
  
  My experience
&lt;/h1&gt;

&lt;p&gt;I have been using Material UI, BaseWeb and Chakra-UI. In my opinion, all of them work very well in their scope. If I would focus on creating a web application mostly to mobile, I would probably use Material UI due to strong similarities to Android design language.&lt;/p&gt;

&lt;p&gt;For smaller projects, I have used BaseWeb and ChakraUI due to easy extendability and CSS-in-JS support. While both felt easy to use and simple to modify to my design, I liked more ChakraUI since it used styled-components.&lt;/p&gt;

&lt;h1&gt;
  
  
  Summary
&lt;/h1&gt;

&lt;p&gt;Component libraries have a long history from the time before React. One of the most popular ones has been Bootstrap but nowadays there are a lot options that work better in React.&lt;/p&gt;

&lt;p&gt;These libraries usually bring a good amount of ready-made components which will ease up the development in the beginning and set a base for a common component library.&lt;/p&gt;

&lt;p&gt;The most popular ready-made component package is Material UI but there are a lot of smaller ones that may give a better result for your specific project.&lt;/p&gt;

&lt;p&gt;The importance is to create the criteria for your project and select the one that fits the best. The criteria can include underlying tools in package, extendability and component amount in relation to what's needed.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;This is a second post from the series *Speed up development by creating a common Component library.&lt;/em&gt; The later posts will cover documentation of common component library.*&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>react</category>
    </item>
    <item>
      <title>Creating a common component library with CSS-in-JS (Styled Components, JSS, Emotion)</title>
      <dc:creator>Aki Rautio</dc:creator>
      <pubDate>Sun, 24 Nov 2019 13:56:21 +0000</pubDate>
      <link>https://dev.to/akirautio/creating-a-common-component-library-with-css-in-js-styled-components-jss-emotion-47j9</link>
      <guid>https://dev.to/akirautio/creating-a-common-component-library-with-css-in-js-styled-components-jss-emotion-47j9</guid>
      <description>&lt;p&gt;CSS-in-JS is a wide term that covers a lot of different practices that enable us to write styles straight to React components. Combining style to functionality gives a lot more flexibility to write state-dependent styles and this also fixes the issue of having the only one namespace.&lt;/p&gt;

&lt;p&gt;In a most simplistic form, this can be done by writing styles straight to HTML tags through a style property but for any bigger application, this brings some downsides. Even though the styles are written multiple times, inline styling will be kept in DOM under each component which increases the size of the DOM very fast and decreases the performance. Luckily there are many ways to solve this issue.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;Component&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;div&lt;/span&gt; &lt;span class="nx"&gt;style&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{{&lt;/span&gt;
    &lt;span class="na"&gt;backgroundColor&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;black&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;border&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;1px solid black&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
    &lt;span class="p"&gt;}}&lt;/span&gt;
  &lt;span class="p"&gt;{...&lt;/span&gt;&lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;  
  &lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;children&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/div&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  Tools
&lt;/h1&gt;

&lt;p&gt;CSS-in-JS packages focus on enhancing a developer experience by bringing better extendability and theming, and performance by compiling styles back to CSS classes. Due to a fastly increased interest in this technique, a lot of packages have been created to include styling to React components. One of the most popular actively developed packages are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/styled-components/styled-components"&gt;Styled Components&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/emotion-js/emotion"&gt;Emotion&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/cssinjs/jss"&gt;JSS&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/styletron/styletron"&gt;Styledtron&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/callstack/linaria"&gt;Linaria&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Besides these, there are a lot of different &lt;a href="https://github.com/A-gambit/CSS-IN-JS-Benchmarks/blob/master/RESULT.md"&gt;options&lt;/a&gt; so you are not limited to these five choices. Though I wouldn't too much look for the performance results since all of the biggest packages are usually fast enough. Most of the tools use randomly generated class names to avoid multiplying styles in DOM.&lt;/p&gt;

&lt;p&gt;In general, these tools can be split into two categories; ones which help out creating class names easier (like JSS and Linaria) and ones that abstract the class names (like Styled Components or Emotion).&lt;/p&gt;

&lt;h2&gt;
  
  
  Setup
&lt;/h2&gt;

&lt;p&gt;Unlike CSS and SASS, CSS-in-JS doesn't need a complicated setup because it doesn't require compiling. The minimum setup is to install the package and import it when needed.&lt;/p&gt;

&lt;h2&gt;
  
  
  Example with JSS
&lt;/h2&gt;

&lt;p&gt;JSS does styling by generating a random class name based on given configuration and this class name which then can be used in the component. It automatically adds CSS under head tag so we don't have to worry about it.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;react&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;createUseStyles&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;useTheme&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;react-jss&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;useStyles&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;createUseStyles&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;myButton&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;padding&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;theme&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;big&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="mi"&gt;8&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;&amp;amp; span&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;fontWeight&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;bold&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;white&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;JSSButton&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;children&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;big&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="nx"&gt;props&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;classes&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;useStyles&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;big&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="nx"&gt;props&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;button&lt;/span&gt; &lt;span class="nx"&gt;className&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;classes&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;myButton&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;span&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;children&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/span&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/button&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;  &lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Example with Styled components
&lt;/h2&gt;

&lt;p&gt;Styled components handle both component and styles together inside the styled function and it enables us to use &lt;a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Template_literals"&gt;template literals&lt;/a&gt; when creating styles, which is pretty close to normal CSS.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;StyledButton&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;styled&lt;/span&gt;&lt;span class="p"&gt;(({&lt;/span&gt; &lt;span class="nx"&gt;children&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="nx"&gt;props&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;button&lt;/span&gt; &lt;span class="p"&gt;{...&lt;/span&gt;&lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;span&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;children&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/span&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;  &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/button&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;&lt;span class="s2"&gt;`
  padding: &lt;/span&gt;&lt;span class="p"&gt;${({&lt;/span&gt; &lt;span class="nx"&gt;big&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;big&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;8px&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;4px&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)}&lt;/span&gt;&lt;span class="s2"&gt;;
  &amp;amp; span {
    font-weight: bold;
    color: white;
  }
`&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  Extending
&lt;/h1&gt;

&lt;p&gt;One of the greatest features on CSS-in-JS is extendability. This makes it very easy to create common components which can be later extended to more detailed. For example if we would like to extend the StyledButton to have extra borders, it would look like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;BorderedStyledButton&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;styled&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;StyledButton&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="s2"&gt;`
  border: 1px solid black;
`&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Extendability brings the power to modify the base elements as much as needed but it also poses risk to have an inconsistent design due to many extended features. That's why it should be used only when we add extra feature like rotatability to Icon or hover effect to specific places.&lt;/p&gt;

&lt;h1&gt;
  
  
  Theming
&lt;/h1&gt;

&lt;p&gt;Most of the CSS-in-JS packages also provide theming support. In theming we separate common variables like colors to the shared location. When the color is used in component, we refer it by the variable name instead of writing the color code.&lt;/p&gt;

&lt;p&gt;For example in JSS and Styled Components theming works he same way as &lt;a href="https://reactjs.org/docs/context.html"&gt;Context&lt;/a&gt;. First the application is wrapped with ThemeProvider and thne all theme variables are available to be used inside the theming through provider hook or props.&lt;/p&gt;

&lt;h2&gt;
  
  
  JSS example
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;ThemeProvider&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;createUseStyles&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;useTheme&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="err"&gt; &lt;/span&gt;&lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;react-jss&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; 

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;useStyles&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;createUseStyles&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;theme&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;myButton&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;background&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;theme&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;colorPrimary&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}))&lt;/span&gt;


&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;JSSButton&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;children&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;big&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="nx"&gt;props&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;theme&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;useTheme&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="c1"&gt;// This provides theme variables&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;classes&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;useStyles&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;big&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;theme&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;button&lt;/span&gt; &lt;span class="nx"&gt;className&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;classes&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;myButton&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;span&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;children&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/span&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/button&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;  &lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;App&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;ThemeProvider&lt;/span&gt; &lt;span class="nx"&gt;theme&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{{&lt;/span&gt; &lt;span class="na"&gt;colorPrimary&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;green&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;}}&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;JSSButton&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/ThemeProvider&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Styled components example
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;styled&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;ThemeProvider&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;styled-components&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;


&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;StyledButton&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;styled&lt;/span&gt;&lt;span class="p"&gt;(({&lt;/span&gt; &lt;span class="nx"&gt;children&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="nx"&gt;props&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;button&lt;/span&gt; &lt;span class="p"&gt;{...&lt;/span&gt;&lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;span&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;children&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/span&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;  &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/button&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;&lt;span class="s2"&gt;`
  background: &lt;/span&gt;&lt;span class="p"&gt;${({&lt;/span&gt; &lt;span class="nx"&gt;theme&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;theme&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;colorPrimary&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;; // Theme is provided automatically
`&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;App&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;ThemeProvider&lt;/span&gt; &lt;span class="nx"&gt;theme&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{{&lt;/span&gt; &lt;span class="na"&gt;colorPrimary&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;green&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;}}&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;StyledButton&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/ThemeProvider&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  My experience
&lt;/h1&gt;

&lt;p&gt;I have been using CSS-in-JS packages for some of my projects and my personal preference has been using packages that hide the className assignment. For bigger projects, I have been relying on Styled Components with &lt;a href="https://github.com/styled-system/styled-system"&gt;styled-system&lt;/a&gt; while &lt;a href="https://github.com/cxs-css/cxs"&gt;CXS&lt;/a&gt; has been used in smaller ones. &lt;/p&gt;

&lt;p&gt;In my opinion, CSS-in-JS brings value by abstracting the styling inside component which functionality and design in one place.  This unifies the way I work with the components and it makes style properties (like big in a button example) to be just one parameter in a component.&lt;/p&gt;

&lt;p&gt;Using CSS-in-JS to create a common component library makes a lot of sense since the key design can be capsulated inside the component and only needed properties can be exposed. This also helps developers who use common components to get an idea what they can change.&lt;/p&gt;

&lt;p&gt;CSS-in-JS also makes extending components much easier and more comprehensible and this pushes to create a simple base component that can be enhanced on a need-based basis. Having a set of common extensible components makes development much faster as you never have to start from the beginning. &lt;/p&gt;

&lt;p&gt;The downside is that this is a very developer-friendly way to handle styling so a person without knowledge of javascript may not be able to do much. This matters a lot when the project involves people with different skillsets.&lt;/p&gt;

&lt;h1&gt;
  
  
  Summary
&lt;/h1&gt;

&lt;p&gt;The biggest advantages of CSS-in-JS are a lack of common namespace which ensures that styles will never collide and easy extendability. On the other hand, the enchancements makes the styles harder to read for the people who haven't been used to the javascript. &lt;/p&gt;

&lt;p&gt;CSS-in-JS can be written without any packages, but the biggest value comes when it's combined with a package that handles the conversion from the style to the class name. The biggest difference between packages is whether they abstract only the class name generation or the whole component generation.&lt;/p&gt;

&lt;p&gt;Repository &lt;a href="https://github.com/ARautio/common-components-post/tree/master/packages/css-in-js"&gt;css-in-js&lt;/a&gt; has an example how to use this in a project.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;This is a third post from the series Speed up development by creating a common Component library. The later posts will cover up the other options to build the common component library and how to document the library.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>styledcomponents</category>
      <category>react</category>
      <category>javascript</category>
      <category>css</category>
    </item>
    <item>
      <title>Creating a common component library with CSS and SASS in React.</title>
      <dc:creator>Aki Rautio</dc:creator>
      <pubDate>Wed, 30 Oct 2019 21:47:04 +0000</pubDate>
      <link>https://dev.to/akirautio/creating-a-common-component-library-with-css-and-sass-in-react-3i2h</link>
      <guid>https://dev.to/akirautio/creating-a-common-component-library-with-css-and-sass-in-react-3i2h</guid>
      <description>&lt;p&gt;There are more than enough options when deciding a toolset for building the common components in React. In this post, we are going to explore how to build common components with CSS and SASS and what kind of benefits and pitfalls there are.&lt;/p&gt;

&lt;p&gt;From the all options, CSS files with &lt;a href="https://sass-lang.com/"&gt;SASS&lt;/a&gt; addition has the lowest learning curve because these tools are used very similarly to a normal web page development. CSS files are very simple to import to React component and SASS gives some nice optional additions like variables and calculations which ease up more complex work.&lt;/p&gt;

&lt;h2&gt;
  
  
  Setup
&lt;/h2&gt;

&lt;p&gt;Setting up a CSS and SASS files to React project also very simple to do whether you are using Create React App or Webpack.&lt;/p&gt;

&lt;h3&gt;
  
  
  Optional: Create a separate component library package
&lt;/h3&gt;

&lt;p&gt;In case you are doing a separate package, you need to take care of both the package and the consumer sides. On a separate package, you can either distribute the CSS files as is and let the consumer do the transpiling or transpile the CSS files already on the package and distribute the result. I would suggest using the first choice since it gives more options to the consumer.&lt;/p&gt;

&lt;p&gt;Doing transpiling on the consumer side makes package creation easy. You need to ensure that both variable and styles files are included in the package when moved to the artifactory. The files need to be just copied to the build directory and then on the consumer side referred like Javascript files:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import '@packagename/styles.css';
import '@packagename/variables.css';
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you want to do transpiling on the package side, you need to use your transpiler to create bundle style files. In case you are not using any bundler, I can suggest &lt;a href="https://rollupjs.org/guide/en/"&gt;Rollup&lt;/a&gt;. Otherwise, find the needed plugin/extension. To transpile the sass files, you can use &lt;a href="https://github.com/egoist/rollup-plugin-postcss"&gt;PostCss&lt;/a&gt; rollup plugin that includes the styles inside the javascript files or creates separate CSS bundle files.&lt;/p&gt;

&lt;p&gt;See example from repository &lt;a href="https://github.com/ARautio/common-components-post/tree/master/packages/css-sass-rollup"&gt;css-sass-rollup&lt;/a&gt; and &lt;a href="https://github.com/ARautio/common-components-post/tree/master/packages/sass-consumer"&gt;sass-consumer&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Create React App
&lt;/h3&gt;

&lt;p&gt;If you are using Create React App you just need to install node-sass.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;npm install node-sass --save-dev&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  Webpack
&lt;/h3&gt;

&lt;p&gt;With webpack, the project needs a bit more configuration but setup is still very straight forward. Besides node-sass we need to install sass-loader, css-loader and style-loader.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;npm install node-sass sass-loader css-loader style-loader --save-dev&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;And then add all these to webpack.config.js&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{
  test: /\.s[ac]ss$/i,
  use: ['style-loader', 'css-loader', 'sass-loader'],
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Parcel
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://parceljs.org/"&gt;Parcel&lt;/a&gt; handles both css and scss out of the box so you can start using them immediately without any configuration.&lt;/p&gt;

&lt;h2&gt;
  
  
  Importing css and scss files
&lt;/h2&gt;

&lt;p&gt;Importing the scss / css files inside a component happens like any other import in javascript. For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;react&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./style.scss&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;Box&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
   &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;div&lt;/span&gt; &lt;span class="nx"&gt;className&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;box&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;Box&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/div&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="nx"&gt;Box&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Once CSS file is imported, the content becomes available everywhere in the application (as long as it is imported). This means you don't necessary have to import the css file where you are using the classes. In a sense this gives a huge flexibility regarding how to handle the styles.  In a most extreme way you could import the css in a root JS file but I wouldn't suggest to do that.&lt;/p&gt;

&lt;h2&gt;
  
  
  How to structure the common components with css
&lt;/h2&gt;

&lt;p&gt;Since CSS has a global namespace, it's very likely that at some point in a project two classnames overlap or otherwise cause issues. To mitigate these this, it's advisable to use some naming convention to separate the component from each other ensure that all unique components have their own classnames. One of the most popular is &lt;a href="https://css-tricks.com/bem-101/"&gt;Block, Element,Modifier (BEM)&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;The idea with naming convention is the use same way to determine the classnames so that they are easy to recognize and reuse. Instead of making the classes be applicable for one use case like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight scss"&gt;&lt;code&gt;&lt;span class="nc"&gt;.disabled_btn&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
 &lt;span class="nl"&gt;border&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;1px&lt;/span&gt; &lt;span class="nb"&gt;solid&lt;/span&gt; &lt;span class="nv"&gt;$color-border&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
 &lt;span class="nl"&gt;border-radius&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nv"&gt;$space-s&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;background-color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nv"&gt;$color-disabled&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nv"&gt;$color-light-text&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We would split the classes to be more generic and only add the necessary additions to more specific classes.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight scss"&gt;&lt;code&gt;&lt;span class="nc"&gt;.btn&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;border&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;1px&lt;/span&gt; &lt;span class="nb"&gt;solid&lt;/span&gt; &lt;span class="nv"&gt;$color-border&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;border-radius&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nv"&gt;$space-s&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nv"&gt;$color-dark-text&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nc"&gt;.btn--disabled&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;background-color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nv"&gt;$color-disabled&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nv"&gt;$color-light-text&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt; 

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  How to use classnames properly
&lt;/h2&gt;

&lt;p&gt;This structure is very extendable and easy to use in different situations. We can use the css straight away:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;CoolButton&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;children&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;classNames&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;onClick&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;button&lt;/span&gt; &lt;span class="nx"&gt;className&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;classNames&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="nx"&gt;onClick&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;onClick&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;children&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;button&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;or build a layer inside the component to handle classnames:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;classnames&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;classnames&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;Button&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;({&lt;/span&gt;&lt;span class="nx"&gt;children&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;disabled&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;onClick&lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;button&lt;/span&gt; 
    &lt;span class="nx"&gt;className&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;classnames&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;btn&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,{&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;btn--disabled&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;disabled&lt;/span&gt; &lt;span class="p"&gt;})}&lt;/span&gt;
    &lt;span class="nx"&gt;onClick&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;onClick&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
   &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;children&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;button&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Note that in the latter example we are using &lt;a href="https://github.com/JedWatson/classnames"&gt;classnames&lt;/a&gt; which helps out handle multiple class names tremendously.&lt;br&gt;
While both ways of using class names are correct, I would strongly recommend using the second one where class names are handled inside the common component and only properties are exposed outside.&lt;/p&gt;

&lt;p&gt;Having properties handle the class name changes limits the amount of available different ways the component can be manipulated, which simplifies the testing and ensuring that the changes won't break the design. &lt;/p&gt;

&lt;p&gt;Unfortunately, there is no way to extend the common component when only exposing the properties so if you need an extendable component, it could be done by creating a base component with className property and build the used component without className property.&lt;/p&gt;

&lt;p&gt;For example if we extend the previous example the used component would look like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;Button&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;({&lt;/span&gt;&lt;span class="nx"&gt;children&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;disabled&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;onClick&lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;CoolButton&lt;/span&gt; 
    &lt;span class="nx"&gt;classNames&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;classnames&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;btn&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,{&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;btn--disabled&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;disabled&lt;/span&gt; &lt;span class="p"&gt;})}&lt;/span&gt;
    &lt;span class="nx"&gt;onClick&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;onClick&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
   &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;children&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;button&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This way we get both extendability and limited amount of options. &lt;/p&gt;

&lt;h2&gt;
  
  
  Using variables from SCSS
&lt;/h2&gt;

&lt;p&gt;Consistent design most often has a defined color palette and standardized spacing. With CSS and SCSS this can be done with variables added to be imported in the root javascript file (for example App.js)&lt;/p&gt;

&lt;p&gt;The scss file could look like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;
&lt;span class="err"&gt;$&lt;/span&gt;&lt;span class="nt"&gt;background-Color&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nt"&gt;global&lt;/span&gt; &lt;span class="nf"&gt;#fff&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
&lt;span class="err"&gt;$&lt;/span&gt;&lt;span class="nt"&gt;primary1Color&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nt"&gt;global&lt;/span&gt; &lt;span class="err"&gt;#408&lt;/span&gt;&lt;span class="nt"&gt;bbd&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
&lt;span class="err"&gt;$&lt;/span&gt;&lt;span class="nt"&gt;primary2Color&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nt"&gt;global&lt;/span&gt; &lt;span class="err"&gt;#408&lt;/span&gt;&lt;span class="nt"&gt;bbd&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
&lt;span class="err"&gt;$&lt;/span&gt;&lt;span class="nt"&gt;secondary1Color&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nt"&gt;global&lt;/span&gt; &lt;span class="nt"&gt;none&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
&lt;span class="err"&gt;$&lt;/span&gt;&lt;span class="nt"&gt;secondary2Color&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nt"&gt;global&lt;/span&gt; &lt;span class="err"&gt;#61&lt;/span&gt;&lt;span class="nt"&gt;b0e7&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
&lt;span class="o"&gt;...&lt;/span&gt;
&lt;span class="err"&gt;$&lt;/span&gt;&lt;span class="nt"&gt;sSpacing&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nt"&gt;global&lt;/span&gt; &lt;span class="s2"&gt;'3px'&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
&lt;span class="err"&gt;$&lt;/span&gt;&lt;span class="nt"&gt;mSpacing&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nt"&gt;global&lt;/span&gt; &lt;span class="s2"&gt;'6px'&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
&lt;span class="err"&gt;$&lt;/span&gt;&lt;span class="nt"&gt;lSpacing&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nt"&gt;global&lt;/span&gt; &lt;span class="s2"&gt;'12px'&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
&lt;span class="o"&gt;...&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And to be used other scss files like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;
&lt;span class="nc"&gt;.btn--primary&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
   &lt;span class="nl"&gt;background-color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="err"&gt;$&lt;/span&gt;&lt;span class="n"&gt;primary1Color&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
   &lt;span class="nl"&gt;padding&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="err"&gt;$&lt;/span&gt;&lt;span class="n"&gt;sSpacing&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If the theme file starts to get bigger, there are also way to use SASS functions and mixins to help out keeping a better structure and easing the usages. &lt;/p&gt;

&lt;p&gt;The benefit of using the global variables comes yet again from restrictions. When you limit yourself to use theme variables when defining colors or spacing, you also make sure that there is an easy overview what different option are used. This makes things yet again easier to test and ensure that everything works as they should. &lt;/p&gt;

&lt;h2&gt;
  
  
  Benefits and drawbacks of using CSS and SASS while creating the common components
&lt;/h2&gt;

&lt;p&gt;As we have seen, CSS and SASS bring a powerful way to do common components/design without adding too much complexity. The component library would be easy to understand even by the developers who haven't done a lot with React and it most likely would be understandable for the people who mainly use only HTML + CSS.&lt;/p&gt;

&lt;p&gt;The biggest advantage to use CSS and SASS is the convertibility. Since the styles are separated from the React component, the style can be reused between the frameworks. This gives a huge advantage if the same design is shared between an application that is not done only with React.&lt;/p&gt;

&lt;p&gt;There are a couple of drawbacks too. Handling the class names manually creates a lot of possibilities to create an unmaintainable mess. The naming convention will help but this needs be managed constantly (or to have proper Eslint rules).&lt;/p&gt;

&lt;p&gt;In my opinion, this toolset is still relevant and should be seen as an equal option when deciding what to use in a project.&lt;/p&gt;

&lt;p&gt;Repository &lt;a href="https://github.com/ARautio/common-components-post/tree/master/packages/css-sass"&gt;css-sass&lt;/a&gt; has an example how to use this in a project.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;This is a second post from the series &lt;strong&gt;Speed up development by creating a common Component library&lt;/strong&gt;. The later posts will cover up the other options to build the common component library and how to document the library.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>react</category>
      <category>css</category>
    </item>
    <item>
      <title>Speed up development by creating a common component library in React</title>
      <dc:creator>Aki Rautio</dc:creator>
      <pubDate>Mon, 30 Sep 2019 20:54:27 +0000</pubDate>
      <link>https://dev.to/akirautio/speed-up-development-by-creating-a-common-component-library-1-introduction-457k</link>
      <guid>https://dev.to/akirautio/speed-up-development-by-creating-a-common-component-library-1-introduction-457k</guid>
      <description>&lt;p&gt;A common component library/design library is a set of visual components that builds up a base for the application. The library usually includes &lt;em&gt;Typography elements&lt;/em&gt; like headings and paragraphs, &lt;em&gt;form elements&lt;/em&gt; like buttons and input fields, and &lt;em&gt;page elements&lt;/em&gt; like tabs and accordions. These can be implemented inside the project or as a separate project.&lt;/p&gt;

&lt;h2&gt;
  
  
  Definition
&lt;/h2&gt;

&lt;p&gt;While a design library often refers only to the visual elements, a common component library can also have components that help out building screens. These may be stack or translation components, for instance. In this series, we speak about a popular library of components, but in most instances, the content also applies to design libraries.&lt;/p&gt;

&lt;p&gt;The scope of the common component system varies depending on the needs, and although some components are included more often than others, each system is unique. &lt;/p&gt;

&lt;h2&gt;
  
  
  Benefits
&lt;/h2&gt;

&lt;p&gt;The main driver to build a common component library is to have a consistent design language between different parts of the application (or between applications) and speed up the development. The key to a successful software project is to strike a balance between software quality and a pace of development, and both sides will benefit from a properly build component library. &lt;/p&gt;

&lt;p&gt;With a common library, there is a possibility to create a reusable set of elements that are well tested. The time used in the beginning to develop the set takes roughly the same time as developing normal components but once they are done, the reuse starts to cut the development speed tremendously.&lt;/p&gt;

&lt;p&gt;For example, form components can have an error handling and loading states included so that they are available for all kinds of components and work the same tested way all the time.&lt;/p&gt;

&lt;h2&gt;
  
  
  Options
&lt;/h2&gt;

&lt;p&gt;When starting up with a common component library, there are three different ways to go:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Use SASS and css classname-helpers&lt;/li&gt;
&lt;li&gt;Use CSS-in-JS like styled-components or emotion&lt;/li&gt;
&lt;li&gt;Use a ready-made component library like Material-UI or base-web&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The correct choice depends on a state of the project because you don't want to rewrite the current component too much. For the new project, all options are good while the existing project should select one which fits the current setup. &lt;/p&gt;

&lt;p&gt;Using a ready-made component library like Material-UI speeds things up hugely in the beginning because there are already a huge amount of commonly used components ready and they only need styling. With two other options, the beginning will be slightly slower because most of the components need to be developed from the beginning. This may end up being beneficial later because ready-made component libraries may lack some needed features which may take more time to develop due to the way the library works.&lt;/p&gt;

&lt;p&gt;There are many good design systems already existing and they can give inspiration for the start. &lt;a href="https://adele.uxpin.com/"&gt;Adele&lt;/a&gt; lists many popular ones and there are a lot more available online.&lt;/p&gt;

&lt;h2&gt;
  
  
  Summary
&lt;/h2&gt;

&lt;p&gt;The key benefit of creating a common component library is to have a set of clearly defined and tested components that can be reused over and over again. This will speed up the development and ensure, the design stays consistent and the code is tested and working. There are a huge amount of different options for React to help out the creation of common components and the right choice depends on the state and needs of the project.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;This is a first post from the series &lt;strong&gt;Speed up development by creating a common component library&lt;/strong&gt;. The later posts will cover different options to build the common component library and how to document the library.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>react</category>
      <category>javascript</category>
    </item>
  </channel>
</rss>
